#include "stdafx.h"
#include <iostream>
using namespace std;
class A {
int x, y;
public: A() { x = y = -1; cout << "Created default" << endl; }
A(int xx, int yy) { x = xx; y = yy; cout << "Created" << endl; }
~A() { cout << "Deleted" << endl; }
void show() { std::cout << x << " " << y << endl; }
};
int _tmain(int argc, _TCHAR* argv[]) {
A a1 = A(10, 10);
a1.show();
cout << "Other values" << endl;
a1 = A(100, 100);
a1.show();
system("pause");
return 0;
}
Повторная инициализация объекта класса
Очень удивился, когда увидел, что деструктор вызывается после вызова второго конструктора, а не до. Ведь логичнее было бы разрушить старый объект перед созданием нового, а здесь получается, что сначала имеем один объект, потом реинициализиреум его поля, потом вызываем деструктор, потом работаем с новымыми значениеями полей. Почему в таком странном порядке идет работа? Ладно еще, если не используем динамическую память (хотя зачем нам деструктор без нее?), - тогда внешне все в порядке. А вот если попробовать вызвать a1.show() после второй инициализации, то сначала вместо значения, хранящегося в p получим какое-то произвольное число, а потом вылетит исключение.
Ниже вывод программы и код.
Вывод.
Цитата:
Created
10 10
Other values
Created
Deleted
100 100
Для продолжения нажмите любую клавишу . . .
10 10
Other values
Created
Deleted
100 100
Для продолжения нажмите любую клавишу . . .
Код без указателя.
Код:
Код с указателем.
Код:
#include "stdafx.h"
#include <iostream>
using namespace std;
class A {
int x, y, *p;
public: A() { x = y = -1; p = new int(100); cout << "Created default" << endl; }
A(int xx, int yy) { x = xx; y = yy; p = new int(100); cout << "Created" << endl; }
~A() { delete p; cout << "Deleted" << endl; }
void show() { std::cout << x << " " << y << " " << *p << endl; }
};
int _tmain(int argc, _TCHAR* argv[]) {
A a1 = A(10, 10);
a1.show();
cout << "Other values" << endl;
a1 = A(100, 100);
a1.show();
system("pause");
return 0;
}
#include <iostream>
using namespace std;
class A {
int x, y, *p;
public: A() { x = y = -1; p = new int(100); cout << "Created default" << endl; }
A(int xx, int yy) { x = xx; y = yy; p = new int(100); cout << "Created" << endl; }
~A() { delete p; cout << "Deleted" << endl; }
void show() { std::cout << x << " " << y << " " << *p << endl; }
};
int _tmain(int argc, _TCHAR* argv[]) {
A a1 = A(10, 10);
a1.show();
cout << "Other values" << endl;
a1 = A(100, 100);
a1.show();
system("pause");
return 0;
}
Код:
a1 = A(100, 100);
здесь происходит копирование:
создается временный объект
полям объекта а1 присваиваются значения соответствующих полей временного объекта
временный объект удаляется
в варианте с указателем будет ошибка доступа:
a1.p будет указывать на ту же область памяти, что и соответствующее поле временного объекта
после копирования вызывается деструктор временного объекта и освобождает эту область памяти
a1.p продолжает указывать на освобожденную область памяти - что и является причиной ошибки
да, потом еще:
на область памяти на которую указывал a1.p до копирования, уже никто не ссылается - т.е. имеет место утечка памяти
деструктор a1 попытается удалить область памяти, которую уже освободил деструктор временного объекта - здесь и проявляется ошибка доступа