CArray + Template
От: fin Россия http://limits.ru
Дата: 22.09.03 04:31
Оценка:
Имеется класс:
MyClass::MyClass()
{
    printf("MyClass::MyClass()\n");
}

MyClass::~MyClass()
{
    printf("MyClass::~MyClass()\n");
}

MyClass::MyClass(const MyClass &obj)
{
    printf("MyClass::MyClass(const MyClass &obj)\n");

    sName = obj.sName;
}

MyClass MyClass::operator =(const MyClass &obj)
{
    printf("MyClass MyClass::operator =(const MyClass &obj)\n");

    sName = obj.sName;
    return *this;
}


Код в главной функции
CArray <MyClass,MyClass&> arrayMyClasses;
cout << "1" << endl;
MyClass obj;
cout << "2" << endl;
obj.sName = "Name";
cout << "3" << endl;
arrayMyClasses.Add(obj);
cout << "4" << endl;


И вот такой странный результат на консоли:
1
MyClass::MyClass()
2
3
MyClass::MyClass()
MyClass MyClass::operator =(const MyClass &obj)
MyClass::MyClass(const MyClass &obj)
MyClass::~MyClass()
4
MyClass::~MyClass()
MyClass::~MyClass()


Почему деструктор вызывается трижды?
Егор Кабанов
Re: CArray + Template
От: Denwer Россия  
Дата: 22.09.03 05:13
Оценка: 3 (1)
Здравствуйте, fin, Вы писали:

fin>Имеется класс:

fin>
fin>MyClass::MyClass()
fin>{
fin>    printf("MyClass::MyClass()\n");
fin>}

fin>MyClass::~MyClass()
fin>{
fin>    printf("MyClass::~MyClass()\n");
fin>}

fin>MyClass::MyClass(const MyClass &obj)
fin>{
fin>    printf("MyClass::MyClass(const MyClass &obj)\n");

fin>    sName = obj.sName;
fin>}

fin>MyClass MyClass::operator =(const MyClass &obj)
fin>{
fin>    printf("MyClass MyClass::operator =(const MyClass &obj)\n");

fin>    sName = obj.sName;
fin>    return *this; //Третий вызов конструктора
fin>}
fin>


fin>Код в главной функции

fin>
fin>CArray <MyClass,MyClass&> arrayMyClasses;
fin>cout << "1" << endl;
fin>MyClass obj; //Первый вызов конструктора
fin>cout << "2" << endl;
fin>obj.sName = "Name";
fin>cout << "3" << endl;
fin>arrayMyClasses.Add(obj); //Второй вызов конструктора
fin>cout << "4" << endl;
fin>


fin>И вот такой странный результат на консоли:

fin>
fin>1
fin>MyClass::MyClass()
fin>2
fin>3
fin>MyClass::MyClass()
fin>MyClass MyClass::operator =(const MyClass &obj)
fin>MyClass::MyClass(const MyClass &obj)
fin>MyClass::~MyClass()
fin>4
fin>MyClass::~MyClass()
fin>MyClass::~MyClass()
fin>


fin>Почему деструктор вызывается трижды?


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

Оставшиеся два вызова конструктора: при создании твоего объекта, и при создании объекта в массиве, ты же там хранишь если так можно сказать копии объектов которые передаешь в функцию Add, если хочешь и этого избежать то сохраняй указатели. Ну соответсвенно тогда получится и деструкторов столько сколько конструкторов(имеется кол-во вызовов конечно).

CArray <MyClass*,MyClass*> arrayMyClasses;
Re[2]: CArray + Template
От: fin Россия http://limits.ru
Дата: 22.09.03 09:02
Оценка:
Здравствуйте, Denwer, Вы писали:

D>Ну все правельно, потому что трижды вызывается конструктор. Кстати на один вызов можно сократить если в операторе присваивания сделать возврат ссылки, тогда вызов конструктора копирования не произойдет(соответсвенно сократится на один и вызов деструктора).


D>Оставшиеся два вызова конструктора: при создании твоего объекта, и при создании объекта в массиве, ты же там хранишь если так можно сказать копии объектов которые передаешь в функцию Add, если хочешь и этого избежать то сохраняй указатели. Ну соответсвенно тогда получится и деструкторов столько сколько конструкторов(имеется кол-во вызовов конечно).


D>
D>CArray <MyClass*,MyClass*> arrayMyClasses;
D>


Однако, при таком способе обявления нельзя будет добавлять не динамически выделенные объекты, стековые например, объявленные в теле функции. При завершении функции объект будет разрушаться а указатель хранящийся в arrayMyClasses будет указывать на освобожденную область памяти. А в общем, это менее избыточный способ с точки зрения ресурсоемкости.
Егор Кабанов
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.