【问题标题】:Why is destructor not called for private nested class in c++?为什么 c++ 中的私有嵌套类不调用析构函数?
【发布时间】:2023-04-07 10:41:01
【问题描述】:

这是我在 Car.h 中的代码

#pragma once

#include<iostream>
#include<string>
using namespace std;

class Car
{

private:
    int speed;
    class GearBox;
    GearBox& gearBox;

public:
    Car();
    ~Car();
};

class Car::GearBox {
private:
    int gear;

public:
    GearBox();
    ~GearBox();
};

在 Car.cpp 我有

#include"Car.h"


    Car::Car(): speed(0), gearBox(GearBox())
{
    cout << "Car constructor" << endl;

}


Car::~Car()
{
    cout << "Car destructor" << endl;
}

Car::GearBox::GearBox(): gear(0)
{
    cout << "Gearbox constructor" << endl;
}

Car::GearBox::~GearBox()
{
    cout << "GearBox destructor" << endl;
}

我的主要是:

#include"Car.h"


int main() {

    {
        cout << "Starting program!" << endl;

        Car car;

    }

    system("PAUSE");
    return 0;
}

程序的结果是: 启动程序! 齿轮箱构造函数 汽车构造器 汽车破坏者

为什么没有输出 Gearbox 析构函数? (对我来说,汽车引用他的变速箱是有道理的,因为变速箱应该存在而汽车确实存在)

【问题讨论】:

  • 您在使用 MSVS 吗?如果您注意到 gearBox(GearBox()) 是非法的,因为您将临时绑定到左值引用。
  • 该代码不是有效的 C++。左值引用不绑定到右值。
  • @NathanOliver 是的,我正在使用 MSVS。好的那为什么程序编译成功了?我怎样才能做到这一点?
  • @Bunc 我编译是因为微软决定允许它编译。这是一个邪恶的扩展,应该被删除。您可以使用 const &amp; 捕获临时文件,但无法修改它。
  • 我在 VS2013 中使用了你的代码。它有效,并且调用了两个析构函数。我也收到了警告 - C4413。 Gear的析构函数在Car的析构函数之前调用,这看起来很正常。这辆车只引用了 Gear。

标签: c++ class nested destructor private


【解决方案1】:

这必须是一个编译器错误,可能与它首先允许引用初始化这一事实有关(这是一个 Visual Studio 扩展,不符合任何实际的、标准化的 C++ 语言版本)。

我相信我可以使用在线 VS 编译器重现这一点:

允许 C++ 编译器省略复制操作,即使它们包含这样的输出,但不能包含构造函数和析构函数。

【讨论】:

  • @bunc:是的,好吧,那是错误。尝试在 MS Connect 上发布
  • 内存泄漏的负责人不是编译器而是开发者。
  • @nariuji:这不是内存泄漏。或者,如果是,那肯定是编译器的错。该程序格式良好,因此开发人员已履行其职责。
  • 引用变量的成员保留普通的临时实例是错误的。那是一个错误。在父类的构造函数中初始化引用变量的情况下,调用临时类的析构函数的安全性在哪里?
  • @nariuji:不,这不是错误;它是一个著名的 Visual Studio 扩展。当临时对象超出范围时不会调用临时对象的析构函数,这是一个错误。诚然,当支持引用初始化不合规时,很难称这种不合规行为开始......但我想说很明显,未能销毁对象不是任何编译器的预期行为。跨度>
【解决方案2】:

GearBox 是否已实例化?

Car::Car(): speed(0), gearBox(GearBox())
{
    cout << "Car constructor" << endl;
}

 ↓

Car::Car(): speed(0)
{
static GearBox inst;
gearBox = inst;
cout &lt;&lt; "Car constructor" &lt;&lt; endl;
}

编辑:

class Car
{
private:
    int speed;
    class GearBox { // referable
    private:
        int gear;
    public:
        GearBox() : gear(0) {
            cout << "Gearbox constructor" << endl;
        }
        ~GearBox() {
            cout << "GearBox destructor" << endl;
        }
    };
    GearBox* gearBox;

public:
    Car();
    ~Car();
};

Car::Car(): speed(0)
{
    static GearBox inst;
    gearBox = &inst;
    cout << "Car constructor" << endl;
}

【讨论】:

  • 虽然可以编译,但是代码不工作又有什么意义呢? :D
猜你喜欢
  • 2023-03-23
  • 1970-01-01
  • 2013-12-17
  • 2014-06-11
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 2011-12-13
相关资源
最近更新 更多