【问题标题】:C++: When and why is the destructor called?C++:何时以及为何调用析构函数?
【发布时间】:2013-03-29 13:04:56
【问题描述】:

我有一个简单的程序来测试我的两个 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;
}

【问题讨论】:

  • 不可能。向我们展示更多代码
  • 请贴出 Vec3.h 的代码
  • 也可能用于Vec3.cpp
  • 顺便说一句,正确的术语是 destructor,而不是 deconstructor。
  • 如果 Vec3 内部的调试输出如大家所想的那样实现,则不会发生......因此 Vec3.cpp 的问题。

标签: c++ destructor destroy


【解决方案1】:

您的调试输出(使用operator&lt;&lt;)会导致一个副本(因为它需要“Vec3”的值)和额外的破坏。

您没有提供复制构造函数,因此您看不到这一点。但如果你愿意,你会发现实际上破坏并不多于构造。

【讨论】:

    【解决方案2】:

    看看输出 - 你创建了一个 Vec3,然后它被销毁,然后在最后 Vec3 被销毁......嗯,很明显你在中间创建了另一个 Vec3,它是一个副本您想要创建的 Vec3。

    所以这看起来是个问题,当您的代码中的某些内容正在制作副本,而该副本又被破坏时,您会将 Vec3s 的输出与单个对象混淆。发生这种混淆的原因是因为您没有定义一个复制构造函数,它也打印出“创建”行。

    所以,首先通过在代码中添加一个复制构造函数来采用最佳实践(提示:如果你有 1 个构造函数、析构函数或复制-ctor,你应该实现所有 3 个。如果你错过任何一个,编译器将把一个给你)。

    【讨论】:

      猜你喜欢
      • 2020-06-07
      • 2010-11-19
      • 1970-01-01
      • 2018-09-01
      • 2012-05-20
      • 2015-08-22
      • 1970-01-01
      • 2020-11-01
      • 2012-06-16
      相关资源
      最近更新 更多