C ++: когда и почему вызывается деструктор?

У меня есть простая программа, чтобы проверить, работает ли мой перекрестный продукт двух 3D-векторов.

#include <iostream>
#include "math\Vec3.h"
using namespace std;

int main(int argc, char **argv)
{
Vec3 v1(1, 23, 5);
Vec3 v2(7, 3, 4);
cout << "Crossing v1 and v2" << endl;
Vec3 v3 = v1.cross(v2);
cout << "crossed" << endl;
return 0;
}

Почему деструктор был вызван сразу после создания переменной?
Вот что он распечатал:

Created: Vec3[1, 23, 5]
Destroy: Vec3[1, 23, 5]     // Why is the vector destroyed here?
Created: Vec3[7, 3, 4]
Destroy: Vec3[7, 3, 4]      // And here?
Crossing v1 and v2
Created: Vec3[77, 31, -158]
Destroy: Vec3[77, 31, -158] //And here??
crossed
Destroy: Vec3[77, 31, -158]
Destroy: Vec3[7, 3, 4]
Destroy: Vec3[1, 23, 5]

Process returned 0 (0x0)   execution time : 0.090 s
Press any key to continue.

Вот Vec3.h:

#include <iostream>
#include <string>

struct Vec3
{
float x, y, z;

Vec3():
x(0), y(0), z(0) { std::cout << "Created: " << *this << std::endl; };
Vec3(float i, float j, float k):
x(i), y(j), z(k) { std::cout << "Created: " << *this << std::endl; };

//...

double dot(const Vec3&);
Vec3 cross(const Vec3&);friend std::ostream& operator<<(std::ostream&, const Vec3);

//...

~Vec3();
};

Vec.cpp:

Vec3 Vec3::cross(const Vec3& v)
{
return Vec3(y * v.z - z * v.y,
z * v.x - x * v.z,
x * v.y - y * v.x);
}

std::ostream& operator<<(std::ostream& out, const Vec3 v)
{
out << "Vec3[" << v.x << ", " << v.y << ", " << v.z << "]";
return out;
}

Vec3::~Vec3()
{
std::cout << "Destroy: "<< "Vec3[" << x << ", " << y << ", " << z << "]"<< std::endl;
}

2

Решение

Ваш отладочный вывод (используя operator<<) вызывает копию (потому что она принимает ‘Vec3’ по значению) и дополнительное уничтожение.

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

7

Другие решения

Посмотрите на результат — вы создаете Vec3, затем он разрушается, и если потом, в самом конце, Vec3 разрушается … хм, очевидно, у вас есть еще один Vec3, созданный в середине, и это копия Vec3 ты хотел создать.

Так что похоже на проблему, вы путаете вывод Vec3s с одним объектом, когда что-то в вашем коде создает копию, которая в свою очередь уничтожается. Причина, по которой эта путаница возникает, заключается в том, что у вас не определен конструктор копирования, который также печатает строку «созданный».

Итак, сначала примените лучшие практики, добавив конструктор копирования в ваш код (подсказка: если у вас есть 1 конструктор, деструктор или copy-ctor, вы должны реализовать все 3. Если вы пропустите какой-либо из них, компилятор вставит один для вы).

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector