gpt4 book ai didi

c++ - 使用继承时构造函数/析构函数调用的顺序

转载 作者:太空狗 更新时间:2023-10-29 21:16:53 25 4
gpt4 key购买 nike

我试图通过编写一些示例代码并尝试遵循程序流程来理解构造函数和析构函数的调用顺序。在大多数情况下,我能够理解(在需要时借助 Google 的帮助)。但是,在一个特定案例中,我遇到了一些障碍。

这是我正在使用的程序:

#include <iostream>
class baseC
{

public:
baseC() { std::cout << "Calling constructor of base class: " << std::endl; }
virtual char const * getName(){ return "Base Class";}
~baseC(){ std::cout << "Calling destructor of base class: " << std::endl;}
};

class childC : public baseC
{
public:
childC() { std::cout << "Calling constructor of child class: " << std::endl; }
char const * getName(){ return "Child Class";}
~childC(){ std::cout << "Calling destructor of child class: " << std::endl; }
};

int main()
{
baseC c3 = childC();
std::cout << c3.getName() << std::endl;
}

这是我得到的输出:

$ g++ test_vd_se.cpp -o test; ./test
Calling constructor of base class:
Calling constructor of child class:
Calling destructor of child class:
Calling destructor of base class:
Base Class
Calling destructor of base class:

编译器似乎首先创建一个基类和子类(这是预期的),但是它继续销毁这两个类,但它可以从基类调用成员函数并继续销毁基类再次上课。

如果有人能解释为什么函数按此顺序调用,我将不胜感激。

最佳答案

这里的问题是您正在切片对象。

baseC c3 = childC();

将创建一个临时的 childC,然后将该对象复制到 c3 中。这就是为什么你看到

Calling constructor of base class:  // create base part of temporary
Calling constructor of child class: // create temporary

// the copy happens here but you do not output when copying

Calling destructor of child class: // destroy base part of temporary
Calling destructor of base class: // destroy temporary

正确的方法是使用智能指针。如果将 main() 更改为

int main()
{
auto c3 = std::make_unique<childC>();
std::cout << c3->getName() << std::endl;
}

或者如果您无权访问智能指针:

int main()
{
baseC* c3 = new childC();
std::cout << c3->getName() << std::endl;
delete c3;
}

你得到:

Calling constructor of base class: 
Calling constructor of child class:
Child Class
Calling destructor of child class:
Calling destructor of base class:

Live Example

我们还需要使 ~baseC() virtual 以便调用正确的析构函数。

virtual ~baseC(){ std::cout << "Calling destructor of base class: " << std::endl;}

您还会注意到,现在打印的是 Child Class 而不是 Base Class,因为现在我们有一个指针动态调度启动并且它调用了正确的虚函数。

关于c++ - 使用继承时构造函数/析构函数调用的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34335253/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com