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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Конструкторы и деструкторы... Зачем они вообще нужны? 
:(
    Опции темы
hoz
Дата 2.2.2014, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



 Изучаю по тиху тему классов и попутно появляются всяческие грабли. Читаю Страуструпа и некоторые другие книги, но в целом не всё понимаю, т.к. по ходу они рассчитаны на более подготовленного читателя. 
На данный момент, не въезжаю значимости операторов конструкторов и деструкторов. Зачем они вообще нужны? Есть ли необходимость их использования?
Я так понимаю конструкторы, если не задать самому, то они задаются неявно. Но причин и необходимости их использования не представляю. Без конструкторов что классы не будут работать?
PM MAIL   Вверх
bsa
Дата 2.2.2014, 16:20 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



конструкторы нужны для первоначальной инициализации объекта класса. А деструкторы для освобождения ресурсов, захваченных объектом класса.
Например. Делаешь ты класс строка. Этот класс имеет внутри только одно приватное поле (для простоты) - указатель на массив символов. Вот ты создал объект этого класса. Куда будет указывать этот указатель? Без конструктора, который проинициализировал бы его, он будет указывать НЕИЗВЕСТНО КУДА. Таким образом, первая же попытка использовать объект приведет к краху программы. Допустим, с конструктором все нормально и ты воспользовался этим объектом. Он выделил память под массив символов и сохранил туда строку. Работать ты с объектом закончил, а память кто освобождать должен? Вот для этого и существует деструктор.

Не надо читать Страуструпа. Он не для новичков. Почитай литературу из соответствующей темы тут: http://forum.vingrad.ru/index.php?show_typ...&kw=faq-c++
PM   Вверх
hoz
Дата 2.2.2014, 21:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(bsa @ 2.2.2014,  16:20)
конструкторы нужны для первоначальной инициализации объекта класса. А деструкторы для освобождения ресурсов, захваченных объектом класса.
Например. Делаешь ты класс строка. Этот класс имеет внутри только одно приватное поле (для простоты) - указатель на массив символов. Вот ты создал объект этого класса. Куда будет указывать этот указатель? Без конструктора, который проинициализировал бы его, он будет указывать НЕИЗВЕСТНО КУДА. Таким образом, первая же попытка использовать объект приведет к краху программы. Допустим, с конструктором все нормально и ты воспользовался этим объектом. Он выделил память под массив символов и сохранил туда строку. Работать ты с объектом закончил, а память кто освобождать должен? Вот для этого и существует деструктор.

Не надо читать Страуструпа. Он не для новичков. Почитай литературу из соответствующей темы тут: http://forum.vingrad.ru/index.php?show_typ...&kw=faq-c++

Я так понимаю, в классах переменные только объявляют, а конструкторах уже происходит инициализация заданным значением, верно?

 Касательно книг, читаю попутно Дейтела и Стивен Прата как раз рекомендованные. Тока вот застрял на этом моменте.

Сложность в том, что использую просто функции я привык, что в функциях происходит и инициализация и объявление, соответственно я особо не заморачивался по этому поводу. А тут по каким-то непонятным мне причинам всё по сложнее, и инициализация уже - отдельный метод.
PM MAIL   Вверх
Lukkoye
Дата 3.2.2014, 02:11 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата(hoz @  2.2.2014,  21:58 Найти цитируемый пост)
Я так понимаю, в классах переменные только объявляют, а конструкторах уже происходит инициализация заданным значением, верно?

 Касательно книг, читаю попутно Дейтела и Стивен Прата как раз рекомендованные. Тока вот застрял на этом моменте.

Сложность в том, что использую просто функции я привык, что в функциях происходит и инициализация и объявление, соответственно я особо не заморачивался по этому поводу. А тут по каким-то непонятным мне причинам всё по сложнее, и инициализация уже - отдельный метод. 


Вот есть машины: вольво, жигули, мерседесы. Названий марок много, но это все один большой класс "легковых автомобилей".

Класс описывает целую категорию каких то сущностей - их свойства и умения. 

Экземпляр класса машин - конкретный автомобиль, который может иметь марку, цвет, и тп.

Экземпляр класса машин - это объект "автомобиль".

Когда вы описываете в классе переменные, вы указываете - какие свойства будут у экземпляра этого класса.
По факту эти переменные существуют не в классе, а в самом объекте - в автомобиле.

Результат работы конструктора - есть объект, значение которых инициализированы согласно логике работы конструктора.


Вы описали класс машин. Теперь хотите создать собственно автомобиль.
Для этого вы должны запустить конструктор машин:

Машина авто(стартовые_параметры);

Здесь 'Машина' - это имя класса, а 'авто' - имя экземпляра класса, который был создан при помощи конструктора с какими то стартовыми параметрами.

Итого: конструктор класса создает экземпляры класса - объекты.

Диструктор вызывается автоматически в момент, когда у объекта завершается время его жизни.

Например, у вас есть класс, объекты которого для своей работы запрашивают у операционной системы динамическую память. Допустим они делают это в конструкторе.

Когда вы закончите работу с ними, и они вам станут не нужны - они должны будут вернуть системе всю запрошенную память обратно. Иначе получится утечка памяти.

В диструкторе можно прописать что нужно сделать, что бы освободить эту память.
И тогда по завершению времени жизни, объекты автоматически будут освобождать все захваченные ресурсы.

Собственно только для этого диструкторы и существует.
PM MAIL   Вверх
xvr
Дата 3.2.2014, 13:19 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(hoz @  2.2.2014,  21:58 Найти цитируемый пост)
Сложность в том, что использую просто функции я привык, что в функциях происходит и инициализация и объявление, соответственно я особо не заморачивался по этому поводу.

У класса есть большое отличие от функции - время жизни. Все внутренние переменные функции живут только во время ее вызова (оставим за бортом пока статические переменные). Т.е. функция сама себе и конструктор и деструктор. Экземпляр класса же начинает жизнь когда его создали, и живет до тех пор, пока его не уничтожат. За это время к его методам могут обратится любое количество раз, и все его (класса) локальные переменные продолжают существовать. Поэтому сделать 'все в одном' (как с функцией) не получится, и приходится отдельно записывать инициализацию всех локалов и их уничтожение (если надо). Это и есть конструктор и деструктор


PM MAIL   Вверх
hoz
Дата 4.2.2014, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Благодарю Всех за столь прекрасные ответы. Наконец то я понял хотя бы теоритически этот момент.

Цитата(xvr @  3.2.2014,  13:19 Найти цитируемый пост)
и приходится отдельно записывать инициализацию всех локалов и их уничтожение (если надо).

Как я понял уничтожение происходит всегда после выхода из функции, т.е. после её использования. Как это так если надо? Ведь, что б не допустить утечки памяти, как я понял, деструктор вызывается постоянно.
 Или имеется в виду, что если используются типа статические переменные (функции), то тогда данные элементы объектов классов не разрушаются... а остальные разрушаются, так?
PM MAIL   Вверх
xvr
Дата 4.2.2014, 08:36 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(hoz @  4.2.2014,  00:56 Найти цитируемый пост)
Как я понял уничтожение происходит всегда после выхода из функции, т.е. после её использования. Как это так если надо?

Очень просто.
Например есть такая переменная -
Код

char* buffer=new char[1000]; // construction
...
delete[] buffer; // destruction
Если не сделать delete, то сама переменная buffer конечно уничтожится, а вот массив, на который она указывала, останется висеть (образуя memory leak)

PM MAIL   Вверх
baldina
Дата 4.2.2014, 09:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

Репутация: 32
Всего: 101



Цитата(hoz @  4.2.2014,  00:56 Найти цитируемый пост)
уничтожение происходит всегда после выхода из функции

не совсем. 
переменная уничтожается (и вызывается деструктор), когда заканчивается время жизни переменной.
для автоматических (локальных) переменных это блок (фигурные скобочки), в котором они объявлены. 
Код

void foo () {
  int a;

  {
     int b;
  } // <-- разрушается b;
  {
     int с;
  } // <-- разрушается c;
} // <-- разрушается a;


Добавлено через 2 минуты и 19 секунд
http://ideone.com/z1VeHK
PM MAIL   Вверх
borisbn
Дата 4.2.2014, 12:58 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(hoz @  2.2.2014,  21:58 Найти цитируемый пост)
Сложность в том, что использую просто функции я привык, что в функциях происходит и инициализация и объявление, соответственно я особо не заморачивался по этому поводу. А тут по каким-то непонятным мне причинам всё по сложнее, и инициализация уже - отдельный метод.

ИМХО, наоборот - проще.
Вот 2 примера - на Си (с функциями) и на Си++ (с классом):
Код
bool copy2IntFromFile( const char * from, const char * to ) {
    int x, y;
    FILE * inFile = fopen( from, "rb" );
    if ( inFile == NULL ) {
        return false;
    }
    FILE * outFile = fopen( to, "wb" );
    if ( outFile == NULL ) {
        fclose( inFile );
        return false;
    }
    if ( fread( & x, sizeof( x ), 1, inFile ) != 1 ) {
        fclose( inFile );
        fclose( outFile );
        return false;
    }
    fwrite( & x, sizeof( x ), 1, outFile );
    if ( fread( & y, sizeof( y ), 1, inFile ) != 1 ) {
        fclose( inFile );
        fclose( outFile );
        return false;
    }
    fwrite( & y, sizeof( y ), 1, outFile );
    fclose( inFile );
    fclose( outFile );
}


Код

class FILEWrapper {
public:
    FILEWrapper( const char * fileName, const char * mode )
        : m_file( fopen( fileName, mode ) )
    {}
    bool good() const { return m_file != NULL; }
    FILE * getFILE() { return m_file; }
    ~FILEWrapper() {
        if ( good() ) {
            fclose( m_file );
        }
    }
private:
    FILE * m_file;
};

bool copy2IntFromFile( char * from, char * to ) {
    int x, y;
    FILEWrapper inFile( from, "rb" );
    if ( ! inFile.good() ) {
        return false;
    }
    FILEWrapper outFile( to, "wb" );
    if ( ! outFile.good() ) {
        return false;
    }
    if ( fread( & x, sizeof( x ), 1, inFile.getFILE() ) != 1 ) {
        return false;
    }
    fwrite( & x, sizeof( x ), 1, outFile.getFILE() );
    if ( fread( & y, sizeof( y ), 1, inFile.getFILE() ) != 1 ) {
        return false;
    }
    fwrite( & y, sizeof( y ), 1, outFile );
}



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


Крокодил
**


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

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



конструкторы являются одним из "китов" С++ (OOP), так же как и индийские программисты в нынешних реалиях.
на С++ ты можешь писать как почти на С без всяких конструкторов.  Они лишь часть ООП парадигмы, которая не является обязательной, даже при программировании на С++.

Я дэАртаньян, а все гвардейцы кардинала


--------------------
a = a + b; b = a - b; a = a - b;
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0945 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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