我有一个简单的程序来测试我的两个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;
}
答案 0 :(得分:7)
您的调试输出(使用operator<<
)会导致副本(因为它按值取'Vec3')并导致其他破坏。
您没有提供复制构造函数,因此您无法看到它。但是,如果你愿意,你会发现你实际上没有比结构更多的破坏。
答案 1 :(得分:1)
看看输出 - 你创建了一个Vec3,然后它被破坏了,然后就在最后Vec3被破坏了...嗯,显然你在中间创建了另一个Vec3,它是一个副本您想要创建的Vec3。
所以这看起来就像问题一样,当代码中的某些东西反过来被销毁时,你会把Vec3s的输出与单个对象混淆。发生这种混淆的原因是因为您没有定义复制构造函数,也会打印出“已创建”的行。
所以,首先通过在代码中添加一个复制构造函数来采用最佳实践(提示:如果你有1个构造函数,析构函数或者复制函数,你应该实现所有3.如果你错过任何一个,编译器会把一个给你)。