Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为什么析构函数被调用了三次?_C++_Constructor_Destructor - Fatal编程技术网

C++ 为什么析构函数被调用了三次?

C++ 为什么析构函数被调用了三次?,c++,constructor,destructor,C++,Constructor,Destructor,输入: #include <iostream> using namespace std; class SimpleClass { public: SimpleClass() { cout<<"SimpleClass Constructor\n"; } virtual ~SimpleClass() { cout<<"SimpleClass destructor\n"; }

输入:

#include <iostream>
using namespace std;
class SimpleClass
{
    public:

    SimpleClass()
    {
        cout<<"SimpleClass Constructor\n";
    }
    virtual ~SimpleClass()
    {
        cout<<"SimpleClass destructor\n";
    }
};
int main()
{
    SimpleClass a;    
    SimpleClass lol = a;

    SimpleClass b;
    SimpleClass * lol2 = &b;
}
SimpleClass Constructor
SimpleClass Constructor
SimpleClass destructor
SimpleClass destructor
SimpleClass destructor
我不明白为什么析构函数被调用了3次


构造函数只被调用了两次 对
a
lol
b
分别调用一次


要确认这一点,可以向类中添加一个字段,并为每个字段分配一个名称/id,然后在析构函数中打印出来。您还可以打印出
this
的值,它是指向对象的指针。

您有
a
lol
b


也许你可以在
main()
以及构造函数和析构函数中打印它们的地址,然后你就会看到它。

你有3个对象
a
lol
,和
b
。您没有跟踪编译器生成的复制构造函数(此构造函数由
lol
调用),因此只有两个构造函数。

析构函数被调用三次,分别为
a
lol
b


在您的例子中,
a
b
使用
默认构造函数进行实例化。但是请注意,
lol
是使用
copy构造函数来实例化的,因为创建的SimpleClass类的对象正好有3个,但构造函数只调用了2次:

  • 第一个对象是
    a
    ,调用构造函数
  • 第二个是
    lol
    ,它通过隐式定义的复制构造函数从a复制来初始化(从而绕过构造函数)
  • 第三个是
    b
    ,调用您的构造函数
请注意,
lol2
只是指向b的指针,因此不会进行额外调用

正确的名称是“析构函数”,而不是“解构函数”;)


重写复制构造函数,然后您可能会看到一个名为的新构造函数。

因为析构函数对于所有对象都是相同的。

您有3个对象,对吗<代码>a,lol,b
。你期望有多少个析构函数调用?如果您实现了
copy构造函数
,您将看到一个对象被复制。您希望复制多少次?我希望复制2次。因为没有调用
lol
构造函数。问题应该是“为什么只有2个构造函数调用?”@mk1否,复制构造函数是为
lol
调用的。您可以重载此隐式定义的复制构造函数吗?是的,您可以显式将其定义为SimpleClass(const SimpleClass&other)。但这里有一个警告:允许编译器在安全的情况下优化调用。这就是为什么复制构造函数通常不应该有任何副作用(写入cout是副作用)。如果复制构造函数没有输出任何内容,请关闭编译器优化。@AlexJenter:但是如果复制构造函数调用被优化掉了(在本例中不会),析构函数也会被优化,因此构造函数调用仍然==析构函数调用。@Benjamin Lindley:这是正确的,感谢您的有益添加。我并不是说在这个例子中它会被优化,这是一个普遍的警告,这是可能的。
  SimpleClass lol = a;    //calls the default copy constructor which you have not defined