Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Конструктор в стиле ООП или нет? 
:(
    Опции темы
EvilsInterrupt
Дата 19.6.2010, 20:38 (ссылка)    | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



Написал констуктор классу:
Код

cDriver::cDriver(std::string filename)
: m_hSCManager( OpenSCManagerA(NULL,NULL,SC_MANAGER_CREATE_SERVICE) ),
  m_hService(NULL),
  m_Filename(filename), m_SrvName(""), m_Displayname("")
{
  const char * errtxt;
  bool   error = false;
  size_t begin_ = 0;
  size_t end_   = 0;

  do 
  {
    if(!m_hSCManager) {
      error  = true;
      errtxt = "Open Service control manager failed";
      break;
    }

    if(filename.length()<=1) {
      error  = true;
      errtxt =  "Filename isn't specified";
      break;
    }

    /* Detect incomplete filename: example <application.exe "cthulhu.sys"> */
    if(std::find(filename.begin(), filename.end(),'\\')==filename.end())
    {
      char   FullName[MAX_PATH] = {0};
      char * pPartFile = NULL;

      if( !GetFullPathNameA(filename.c_str(),sizeof(FullName),FullName,&pPartFile) )
      {
        error  = true;
        errtxt = "Get full path failed";
        break;
      }

      m_Filename = FullName;
    }

    begin_ = m_Filename.find_last_of('\\') + 1;
    end_   = m_Filename.find_last_of('.');
    if(-1 == end_)
      end_ = m_Filename.length();

    const int MIN_DRVFILE_NAME = 4;
    if(!begin_ || begin_ >= m_Filename.length() - MIN_DRVFILE_NAME) {
      error  = true;
      errtxt = "Filename not stated";
      break;
    }

  } while (false);

  if(error) {
    CloseServiceHandle(m_hSCManager);
    throw(driver_error(errtxt));
  }

  m_SrvName     = m_Filename.substr(begin_,end_ - begin_);
  m_Displayname = m_SrvName + " driver";
}


Хотелось бы узнать, что думает матерый С++ - гуру ? ;) Т.е. с высоты нескольких лет использования ++.

Отмечу, что тут do - whihe нужен для того чтоб свести обработку и корректный откат в одно место! ;)
PM MAIL WWW ICQ Jabber   Вверх
Abyx
Дата 19.6.2010, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 601
Регистрация: 3.11.2009

Репутация: 1
Всего: 10



Это God-Constructor, разновидность God-Function
PM MAIL   Вверх
ISergeyN
Дата 19.6.2010, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 11.10.2008
Где: Україна

Репутация: нет
Всего: 2



Код

cDriver::cDriver(const std::string &filename)

PM MAIL Skype   Вверх
EvilsInterrupt
Дата 19.6.2010, 21:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



ISergeyN, Сделано было специально, потому что думаю что если передам char *, то ахтунг ) Может и ошибаюсь,

Пример, будет ли это работать с добавлением "&"  ? :

cDriver drvr("Cthulhu.sys");

или надо будет:

cDriver drvr(std::string("Cthulhu.sys") );

?

Более, того. Вы предлагаете ссылку, а значит в конструкторе нужно ссылаться на конкретный объект! А что если перечислю список дров для тестировани из ини-файла и удалю их потом ,т.е. все будет в динамике, то на что ссылаться то?

Потому мне кажется лучше по значению, а не ссылке )
PM MAIL WWW ICQ Jabber   Вверх
ISergeyN
Дата 19.6.2010, 21:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 59
Регистрация: 11.10.2008
Где: Україна

Репутация: нет
Всего: 2



Код

#include <iostream>
#include <string>

void func(const std::string &rhs){
    std::cout << rhs << std::endl;
}
 
int main()
{
    func("Hello");
    return 0;
}


http://codepad.org/tPCL89kP
PM MAIL Skype   Вверх
bsa
Дата 19.6.2010, 21:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



EvilsInterrupt, стандартный способ передачи СЛОЖНЫХ объектов в качестве параметра - по константной ссылке. Твои страхи беспочвенны. у std::string конструктор от const char* не explicit, поэтому передавать строковые литералы можно.
PM   Вверх
borisbn
Дата 19.6.2010, 22:17 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Не советую выбрасывать исключения из конструктора - дурной тон


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
EvilsInterrupt
Дата 19.6.2010, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



borisbn, Почему? То что не производительно по скорости выполнения согласен,  но почему дурной тон? Если объект был должен создан,  а он не создался, то что? Это разве просто ошибка? Нет! Это исключительная ситуация!
PM MAIL WWW ICQ Jabber   Вверх
borisbn
Дата 20.6.2010, 06:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



EvilsInterrupt, под руками нет отладчика (к сожалению не помню) чтобы проверить, вызовется ли в этом случае деструктор. А если и вызовется, то как ему удалять наполовину созданный объект. IMHO в ситуации, когда может произойти исключительная ситуация создать отдельную функцию инициализации.
Хотя, ладно, согласен, что и так можно. Просто у нас на фирме это - дурной тон (мы используем Qt, и потихоньку начинаем перенимать их стиль)


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
azesmcar
Дата 20.6.2010, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(borisbn @  19.6.2010,  22:17 Найти цитируемый пост)
Не советую выбрасывать исключения из конструктора - дурной тон 

мало того - опасно!
Код

#include <iostream>
#include <stdexcept>

struct A
{
    void foo()
    {
        throw std::runtime_error("error 1");
    }
    ~A()
    {
        throw std::runtime_error("error 2");
    }
};

int main()
{
    try
    {
        A t;
        t.foo();
    } catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }
}

и еще пример
Код

#include <iostream>
#include <stdexcept>

struct A
{
    ~A()
    {
        throw std::runtime_error("error 2");
    }
};

int main()
{
    try
    {
        A arr[10];
    }
    catch (std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}

тут конечно можно использовать std::uncaught_exception(), но зачем это нужно?
Код

~A()
{
    if (!std::uncaught_exception())
        throw std::runtime_error("error 2");
}


Это сообщение отредактировал(а) azesmcar - 20.6.2010, 09:55
PM   Вверх
cutwater
Дата 20.6.2010, 09:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 592
Регистрация: 24.6.2008

Репутация: 1
Всего: 10



эм... мне кажется или кто-то путает конструктор с деструктором?

ибо в деструкторе да, исключения бросать нельзя.
 а в конструкторе это единственно верный способ сообщить об ошибке.


--------------------
user posted image
PM MAIL   Вверх
azesmcar
Дата 20.6.2010, 09:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(cutwater @  20.6.2010,  09:56 Найти цитируемый пост)
эм... мне кажется или кто-то путает конструктор с деструктором?

черт, написано конструктор, прочитал деструктор smile 

Цитата(cutwater @  20.6.2010,  09:56 Найти цитируемый пост)
ибо в деструкторе да, исключения бросать нельзя.

ну так мой пример про деструкторы smile

Добавлено через 2 минуты и 12 секунд
неправильно прочитал, исправляюсь
Цитата(borisbn @  19.6.2010,  22:17 Найти цитируемый пост)
Не советую выбрасывать исключения из конструктора - дурной тон 

ничего дурного в этом нет. smile 
PM   Вверх
EvilsInterrupt
Дата 20.6.2010, 10:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



>>Это God-Constructor, разновидность God-Function

не совсем понял, что вы хотели сказать? ;) Намек на  то что мне  нужно поискать эти термины и после прочтения пойму, что мой конструктор подходит под то что пишут опытные С++-программеры?

>>а в конструкторе это единственно верный способ сообщить об ошибке.
это не только единственный, это лучше не придумаешь! Нахрена скажите человеку идти в магазин за хлебом, если он забыл дома кошелек? Если в мире людей еще можно  надеяться, что кто-то пожалеет или даст в долг, то в мире программ надеяться на что-то никак нельзя! Если от чего-то зависит нарушение достижения основной цели программы, то это "чего-то" исключительная и мало того экстренная ситуация. Ошибку можно не проверить, а вот исключение оставить обработанным никак нельзя!

>> под руками нет отладчика (к сожалению не помню) чтобы проверить, вызовется ли в этом случае деструктор. А если и вызовется, то как ему удалять наполовину созданный объект.
Простите но  бред! Объект или создается или не создается и объект считается созданным, только тогда,  когда отработала не только секция инициализация конструктора, т.е. после двоеточия, но и само тело! 1) Деструктор будет вызван исключительно только у созданного объекта и никак иначе! 2) Для внутренних объектов деструктор вызывается не только,  когда удаляется сам объект содержащий, но также и тогда, когда не завершилось тело конструктора,к примеру бросили исключение в тело и после обработки его, решено удалить, тогда произойдет откат создания внутренних, за исключением действий по выделению ресурсов в теле конструктора 3) Для этого нужно все что выделил удалить самому!

>>cDriver::cDriver(const std::string &filename)
учту спасибо!!!
Но к вам вопрос. Что если я хочу в методе вернуть std::string, как лучше это осуществить? По значению, по указателю или ссылке на созданный внутри спомощью new ?

Это сообщение отредактировал(а) EvilsInterrupt - 20.6.2010, 11:13
PM MAIL WWW ICQ Jabber   Вверх
borisbn
Дата 20.6.2010, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Код

#include <iostream.h>
#include <stdio.h>

class FileOpener
{
public:
    FileOpener()
        : m_file( 0 )
    {
        std::cout<< "FileOpener::FileOpener()" << std::endl;
        m_file = fopen( "some_file.txt", "wt" );
        if ( m_file )
        {
            fprintf( m_file, "some text\n" );
        }
    }
    ~FileOpener()
    {
        std::cout<< "FileOpener::~FileOpener()" << std::endl;
        if ( m_file )
        {
            fclose( m_file );
        }
    }
private:
    FILE * m_file;
};

class A
{
public:
    A()
        : m_fileOpener( 0 )
    {
        std::cout << "A::A() entry" << std::endl;
        m_fileOpener = new FileOpener();
        std::cout << "A::A() before throw" << std::endl;
        throw( 1 );
    }
    ~A()
    {
        std::cout << "A::~A()" << std::endl;
        delete m_fileOpener;
    }
private:
    FileOpener * m_fileOpener;
};

int main()
{
    std::cout << "entry" << std::endl;
    try
    { 
        A a;
    }
    catch( ... )
    {
        std::cout << "catched" << std::endl;
    }
    std::cout << "exit" << std::endl;
}


Output:
Цитата

entry
A::A() entry
FileOpener::FileOpener()
A::A() before throw
catched
exit


http://codepad.org/knrUAMBO

Это сообщение отредактировал(а) borisbn - 20.6.2010, 10:58


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
EvilsInterrupt
Дата 20.6.2010, 11:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Executables research
***


Профиль
Группа: Завсегдатай
Сообщений: 1019
Регистрация: 14.7.2007
Где: Железнодорожный, МО, Россия

Репутация: 2
Всего: 9



borisbn, С какой целью вы привели свой код? ;) Если просто показать, что ничего такого в бросании ислкючений в конструкторе, то по-моему уже два поста, + мой сегодняшний говорят о том что :
Цитата

ничего дурного в этом нет. 

PM MAIL WWW ICQ Jabber   Вверх
Страницы: (3) Все [1] 2 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1008 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.