【问题标题】:Why is the destructor of a C++ class called upon construction?为什么在构造时调用 C++ 类的析构函数?
【发布时间】:2014-04-22 13:41:26
【问题描述】:

我遇到的问题是在构造类时调用了我的类析构函数。考虑以下测试程序:

#include <iostream>
#include <vector>

using namespace std;

class X
{
public:
    X()  { cout << "X::X()" << endl; };
    ~X() { cout << "X::~X()" << endl; };
};

class Y : public X
{
public:
    Y() : X() { cout << "Y::Y()" << endl; };
    ~Y()      { cout << "Y::~Y()" << endl; };
};

int main() {
    vector<Y> a;
    a.resize(10);
    while(true) ;
    return 0;
}

输出(来自循环之前)是

X::X()
Y::Y()
Y::~Y()
X::~X()

我不明白上面sn-p的行为:

  1. 为什么只构造一个元素?
  2. 为什么要调用析构函数?

【问题讨论】:

  • 如果你去掉无限循环,事情会更清楚,所以你可以看到所有的对象都被销毁了,并提供了详细的复制构造函数和赋值运算符,所以你可以看到所有元素正在构造/分配。
  • 嗨@juanchopanza,感谢您的评论。因为我想让循环之前发生的破坏与由于范围结束而发生的通常破坏区分开来,所以我引入了循环。

标签: c++ inheritance constructor destructor


【解决方案1】:

std::vector::resize()的原型是:

void resize( size_type count, T value = T() );

因此它创建了一个临时默认值以插入到向量中(您的构造函数调用),然后将其复制构造 10 次到向量中(您不记录那些),然后临时被销毁(您的析构函数打电话)。

请注意,对于 C++11,情况发生了变化。现在有两个重载:

void resize( size_type count );
void resize( size_type count, const value_type& value);

因此,如果您使用适当的 C++11 编译器,您将调用第一个重载,并且您的值将被初始化,也就是说,它将使用默认构造函数。

【讨论】:

  • 啊,我明白了。我可以毫不费力地在我的析构函数中检测到这一点以避免释放未分配的内存吗?
  • @Angew:我只是在打字;-)
  • @janoliver 为什么这对你很重要?如果您的班级管理内存(或其他资源),它必须遵循rule of three,因此它应该可以在复制的情况下正常工作(否则它只是等待发生的灾难)。
  • @janoliver:不容易。您似乎想使用不可复制对象的向量,这是一个坏主意。使用指针向量或类似的东西。
  • @Angew:好的,谢谢你的评论。我将深入研究这个“三法则”。
猜你喜欢
  • 2021-04-01
  • 2020-10-29
  • 1970-01-01
  • 2020-08-24
  • 1970-01-01
  • 2013-01-28
  • 2010-10-13
  • 2013-06-20
  • 2013-02-14
相关资源
最近更新 更多