【发布时间】:2020-02-23 01:06:15
【问题描述】:
#include <iostream>
using namespace std;
class Car
{
public:
~Car() { cout << "Car is destructed." << endl; }
};
class Taxi :public Car
{
public:
~Taxi() {cout << "Taxi is destructed." << endl; }
};
void test(Car c) {}
int main()
{
Taxi taxi;
test(taxi);
return 0;
}
这是输出:
Car is destructed.
Car is destructed.
Taxi is destructed.
Car is destructed.
我使用 MS Visual Studio Community 2017(抱歉,我不知道如何查看 Visual C++ 的版本)。
当我使用调试模式时。我发现在按预期离开void test(Car c){ } 函数体时会执行一个析构函数。并且test(taxi);结束时出现了一个额外的析构函数。
test(Car c) 函数使用值作为形式参数。
转到该功能时会复制汽车。
所以我认为离开功能时只会有一个“汽车被破坏”。
但实际上离开函数时有两个“Car is destructed”。(输出中显示的第一行和第二行)
为什么会有两个“汽车被毁”?谢谢。
================
当我在class Car 中添加一个虚函数时
例如:virtual void drive() {}
然后我得到了预期的输出。
Car is destructed.
Taxi is destructed.
Car is destructed.
【问题讨论】:
-
在将
Taxi对象传递给按值获取Car对象的函数时,编译器如何处理对象切片可能是个问题? -
必须是您的旧 C++ 编译器。 g++ 9 给出了预期的结果。使用调试器确定生成对象的额外副本的原因。
-
我已经用 7.4.0 版本测试了 g++,用 6.0.0 版本测试了 clang++。他们给出了与 op 的输出不同的预期输出。所以问题可能与他使用的编译器有关。
-
我用 MS Visual C++ 复制。如果我为
Car添加用户定义的复制构造函数和默认构造函数,那么这个问题就会消失,它会给出预期的结果。 -
请在问题中添加编译器和版本
标签: c++ inheritance visual-studio-2017 destructor pass-by-value