Я новичок в C ++, и я написал небольшую программу, чтобы узнать, как присваивание работает с объектами. Мне было предложено сделать это из документации cpp на этой странице (http://www.cplusplus.com/doc/tutorial/classes2/). На этой странице указано:
Неявная версия [оператора назначения копирования] выполняет поверхностное копирование, которое подходит для многих классов, но не для классов с указателями на объекты, которые они обрабатывают в своем хранилище. В этом случае не только класс подвергается риску удаления указанного объекта дважды, но назначение создает утечки памяти, не удаляя объект, указанный объектом до назначения .
Последняя часть, которую я выделил жирным шрифтом, - это то, почему я решил проверить вещи. Я думал, что эта проблема может быть решена путем обработки удаления указанных объектов в деструкторе (что является стандартным?), Вместо того, чтобы перегружать оператор присваивания копии. Если деструктор не вызывается, разве это не неудобно? Скажем, у меня было несколько ссылочных объектов, я должен был бы поместить все удаления как в деструктор (для большинства случаев перераспределения), так и в перегрузку присваивания.
Во время этого теста я столкнулся с совершенно другой проблемой. Моя первоначальная идея состояла в том, чтобы создать простой класс, который хранит int (в качестве идентификатора для целей тестирования) и перегружает конструкторы и деструкторы, чтобы увидеть, когда и вызывается ли деструктор.
Вот мой код:
class Test{
public:
int id;
explicit Test(int id) : id(id) {
cout << "Created " << id << endl;
}
~Test() {
cout << "Destroyed " << id << endl;
}
};
int main() {
Test x = Test(1);
x = Test(2);
cout << x.id << endl;
return 0;
}
Результат, который я ожидал, должен был быть:
1: Created 1
2: Destroyed 1
? (это был тот, в котором я не был уверен, так как веб-сайт намекал, что этот деструктор не будет вызываться, если объект будет «заменен» другим, а не выходит из области видимости).
3: Created 2
Объект 2 «заменяет» объект 1, поскольку он назначен для x
4: 2
значение идентификатора объекта 2 распечатано
5: Destroyed 2
Объект 2 уничтожен, когда он выходит из области видимости
Вместо этого я получил следующий вывод:
Created 1
Created 2
Destroyed 2
2
Destroyed 2
Это действительно не имеет смысла для меня.
Используя отладчик, Created 2
и Destroyed 2
оба отображаются, когда вызывается строка x = Test(2);
. Если мы просто присвоили x
объекту 2, почему его деструктор вызывается немедленно? Это следует к следующей части.
Во-вторых, поскольку был вызван деструктор для объекта 2, мы можем предположить, что он был уничтожен. Следующий вывод 2
, кажется, противоречит этому, поскольку предполагает, что x
все еще содержит Объект 2 (ожидаемый, но противоречащий вызову его деструктора).
Я не совсем уверен, почему это происходит.
Наконец, Destroyed 2
выводится. Это имело бы смысл, если бы мы не видели это раньше. Объект 2 хранится в x
, поэтому, когда он выходит из области видимости, вызывается деструктор.
По какой-то причине мы получаем деструктор, вызываемый дважды, и Объект 1, который «переопределяется» назначением Объекта 2 на x
, никогда не вызывает своего деструктора, но вместо этого деструктор объекта, который мы только что создали, имеет свой вызван деструктор.
Итак ... это сводится к вопросу из двух частей:
1: Почему происходит это странное поведение, и есть ли логическая причина, почему это так?
2: приводит ли «перезапись» объекта (например, объекта 1) к другому объекту (объекту 2) посредством присваивания к его деструктору (в данном случае деструктору объекта 1) для вызова или нет?
Заранее спасибо.