继承和析构函数-理论问题- c++
Inheritance and destructors - theoretical question - C++
class A
{
public:
virtual void f(){ printf("A.f "); }
~A(){ f(); }
};
class B : public A
{
A a;
public:
void f(){ printf("B.f "); }
B(){ throw -1; }
~B(){ f(); }
};
int main()
{
try{ B b; }
catch(...){ printf("Exc");}
}
我是这么看的。在try块内部,在构造B b;
时没有打印任何东西。街区结束了。我认为编译器首先销毁了A a;
成员。因此,A.f()
将被打印。这是否意味着销毁了class B
实例?之后,编译器会简单地调用~A()
(析构基类)吗?
我想我应该得到A.f()
,然后是B.f()
(析构类B实例),之后是A.f()
(基类的析构函数)。编写这篇文章让我思考了一下。Exc将在课程结束时打印出来。我找了好几个题目都没找到。
编辑:输出Dev-C + + (GCC 3.4.2)
。f A.f Exc
这里确实有两个A
对象。
-
B
继承自A
,因此A
的基类对象在B之前被首先实例化。 - 另一个
A
实例被创建,因为你有一个A
类型的成员字段作为B
的一部分。
当您创建B b
时,您创建了基类A
,以及实例A a
。
但是,您随后在B
的构造函数中抛出异常,因此此时所有完全构造的对象都被析构,即
-
~A()
在实例A a
上被调用。 -
~A()
在基类A
上被调用。
这就解释了为什么你会得到A.f A.f Exc
。
B
的析构函数将不会被调用,因为B
的构造函数没有成功完成而没有完全构造。
您还没有向我们展示您得到的输出,只是一堆乱七八糟的文本,所以很难知道您在问什么。
然而,为了记录,你的代码的输出是:
。f A.f Exc
为什么?
-
b
建设失败 -
b
的B
析构函数没有被调用,但是它的成员的析构函数是1。 - 有一个
A
类型的成员,其析构函数调用f()
函数。 - 还有一个完全构建的
A
基础b
;因此,b
的A
析构函数也被调用,像以前一样调用A::f()
。 -
Exc
当然是由周围的异常处理程序输出。
这是你想知道的吗?
<一口> 1> blockquote>
[n3290: 15.2/2]:
任意存储时间的对象初始化或销毁由异常终止为其所有完全构造的子对象执行析构函数(不包括类联合的变体成员),即for主构造函数(12.6.2)已完成的子对象执行时,析构函数尚未开始执行。[. .]
顺序应为:A.f, A.f, Exc
当调用B的构造函数时,在进入之前,首先由于继承而调用A的构造函数。接下来,在进入B的构造函数之前(即在{
之前),a
是默认构造的。
B的构造只有在满足}
时才算完成。但在那之前,你有一个throw语句。所以部分构造的B必须被销毁,它有一个对象a
和继承的子对象a所以这两个都被销毁了,因此A.f和A.f
接下来,到达输出'Exc'的throw块
#include <stdio.h>
class A
{
public:
virtual void f(int i){ printf("A.f %in", i); }
~A(){ f(0); }
};
class B : public A
{
A a;
public:
void f(int i){ printf("B.f %in", i); }
B(){ throw -1; }
~B(){ f(1); }
};
int main()
{
try{ B b; }
catch(...){ printf("Excn");}
}
A的析构函数被调用两次,就是这样。
输出:A.f 0
A.f 0
Exc
不能从构造函数或析构函数调用虚函数。它们不会作为虚函数工作,而是作为非虚函数调用。
- 警告处理为错误这里有什么问题
- 最小硬币更换问题(自上而下方法)
- 为"adjacent"变量赋值时出现问题
- 我的神经网络不起作用 [XOR 问题]
- 在Ubuntu 16.04上安装Cilk时出现问题
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- Project Euler问题4的错误解决方案
- 问题:什么是QAbstractItemView::NoEditTriggers的反面
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在进程中对同一管道进行读取和写入时C++管道出现问题
- 静态数据成员的问题-修复链接错误会导致编译器错误
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 一个关于在C++中重载布尔运算符的问题
- 首要问题的答案让值班员搞错了
- setlocale的C++土耳其字符串问题
- 如何重构类层次结构以避免菱形问题
- 组合理论的一个问题
- 内存使用的理论和问题
- 继承和析构函数-理论问题- c++