c++ - 怎么可能调用了析构函数但在此之前没有构造函数?
问题描述
我目前正在学习 C++ 的面向对象特性。我写了一段代码来测试继承和多态是如何工作的。这是代码的一部分:
class Person
{
public:
Person()
{
cout << "Person constructed\n";
}
virtual void introduce()
{
cout << "hi from person" << endl;
}
~Person()
{
cout << "Person destructed\n";
}
};
class Student : public Person
{
public:
Student()
{
cout << "Student constructed\n";
}
void introduce()
{
cout << "hi from student" << endl;
}
~Student()
{
cout << "Student destructed\n";
}
};
class Farmer : public Person
{
public:
Farmer()
{
cout << "Farmer constructed\n";
}
void introduce()
{
cout << "hi from farmer" << endl;
}
~Farmer()
{
cout << "Farmer destructed\n";
}
};
class SJW : public Student
{
public:
SJW()
{
cout << "SJW constructed\n";
}
~SJW()
{
cout << "SJW destructed\n";
}
};
void whoisthis3(Person object)
{
object.introduce();
}
int main()
{
Student mark;
SJW bigred;
Farmer max;
cout << endl;
whoisthis3(mark);
whoisthis3(max);
whoisthis3(bigred);
cout << endl;
return 0;
}
这是它产生的输出:
Person constructed
Student constructed
Person constructed
Student constructed
SJW constructed
Person constructed
Farmer constructed
hi from person
Person destructed
hi from person
Person destructed
hi from person
Person destructed
Farmer destructed
Person destructed
SJW destructed
Student destructed
Person destructed
Student destructed
Person destructed
这些派生类在开始和结束时按预期构造和销毁。但是,当 whoisthis3 方法执行时,怎么会调用 Person 析构函数呢?那里发生了什么?
解决方案
考虑以下简单程序:
struct A
{
A() { std::cout << "construct A\n"; }
~A() { std::cout << "destruct A\n"; }
};
int main()
{
A a;
}
这打印:
constructs A
destructs A
正如预期的那样。
现在让我们添加一个简单的函数:
void f(A a) {}
并称之为:
int main()
{
A a;
f(a);
}
我们看到:
construct A
destruct A
destruct A
那额外的钱destruct A
是从哪里来的呢?对应的在哪里construct A
?答案是,当您调用 时f
,会调用默认的复制构造函数。如果您在复制构造函数中打印内容,如下所示:
A(A const&) { std::cout << "copy-construct A\n"; }
然后你得到输出:
construct A
copy-construct A
destruct A
destruct A
这表明确实已经构建了 2 个对象,然后两个对象都被销毁了。
另一方面,如果f
通过引用获取参数,如下所示:
void f(A& a) {}
然后不调用复制构造函数(因为没有复制),输出将是:
construct A
destruct A
推荐阅读
- html - 如何根据父容器内的可用空间在我的元素之间分配相同的高度?(我需要动态解决方案)
- javascript - 画布:删除对象后恢复图像
- python - python entry_point 没有模块名称 __main__
- excel - 运行时错误 5 无效的过程调用或参数
- sql - 计算和平均范围
- c# - C# 9 可空类型问题
- tkinter - tkinter - 定义中只有最后一个选项随着下拉选择而改变
- javascript - 等待 vutify 中的警报对话框响应
- java - 与“C++ 异常处理”相比,“JAVA 异常处理心态”是什么?
- html - CSS:如何使混合模式具有透明背景,仅影响/被剪辑到(文本)内容?