Smg*_*Smg 84 c++ destructor g++
开发环境:GNU GCC(g ++)4.1.2
虽然我正在尝试研究如何在单元测试中增加"代码覆盖率 - 特别是功能覆盖率",但我发现有些类dtor似乎是多次生成的.你们当中有些人知道为什么吗?
我通过使用以下代码尝试并观察了我上面提到的内容.
在"test.h"中
class BaseClass
{
public:
~BaseClass();
void someMethod();
};
class DerivedClass : public BaseClass
{
public:
virtual ~DerivedClass();
virtual void someMethod();
};
Run Code Online (Sandbox Code Playgroud)
在"test.cpp"中
#include <iostream>
#include "test.h"
BaseClass::~BaseClass()
{
std::cout << "BaseClass dtor invoked" << std::endl;
}
void BaseClass::someMethod()
{
std::cout << "Base class method" << std::endl;
}
DerivedClass::~DerivedClass()
{
std::cout << "DerivedClass dtor invoked" << std::endl;
}
void DerivedClass::someMethod()
{
std::cout << "Derived class method" << std::endl;
}
int main()
{
BaseClass* b_ptr = new BaseClass;
b_ptr->someMethod();
delete b_ptr;
}
Run Code Online (Sandbox Code Playgroud)
当我构建上面的代码(g ++ test.cpp -o test),然后看看生成了哪种符号,如下所示,
nm - 降级测试
我可以看到以下输出.
==== following is partial output ====
08048816 T DerivedClass::someMethod()
08048922 T DerivedClass::~DerivedClass()
080489aa T DerivedClass::~DerivedClass()
08048a32 T DerivedClass::~DerivedClass()
08048842 T BaseClass::someMethod()
0804886e T BaseClass::~BaseClass()
080488f6 T BaseClass::~BaseClass()
Run Code Online (Sandbox Code Playgroud)
我的问题如下.
1)为什么生成了多个dtors(BaseClass - 2,DerivedClass - 3)?
2)这些dtors有什么区别?如何有选择地使用这些多个dtors?
我现在有一种感觉,为了实现C++项目的100%功能覆盖,我们需要理解这一点,以便我可以在单元测试中调用所有这些dtors.
如果有人能给我上面的回复,我会非常感激.
bdo*_*lan 67
首先,这些功能的目的在Itanium C++ ABI中描述; 请参阅"base object析构函数","完整对象析构函数"和"删除析构函数"下的定义.5.1.4中给出了到损坏名称的映射.
基本上:
operator delete实际释放内存.如果没有虚拟基类,则D2和D1相同; 在足够的优化级别上,GCC实际上将符号别名为两者的相同代码.
Sim*_*ter 37
通常有两种构造函数(非充电/负责)和三种析构函数(非充电/充电/充电删除).
在未在充电构造函数和析构函数被处理,使用从另一个类继承的类的对象时使用的virtual关键字,当对象是不完整的对象(因此当前对象是"不充电"构造或自毁的虚拟基础对象).该ctor接收指向虚拟基础对象的指针并存储它.
该主管构造函数和dtors对于所有其他情况,也就是说,如果没有涉及虚拟继承; 如果类具有虚拟析构函数,则负责删除 dtor指针进入vtable槽,而知道对象动态类型的范围(即对于具有自动或静态存储持续时间的对象)将使用负责人 dtor (因为不应该释放这个内存).
代码示例:
struct foo {
foo(int);
virtual ~foo(void);
int bar;
};
struct baz : virtual foo {
baz(void);
virtual ~baz(void);
};
struct quux : baz {
quux(void);
virtual ~quux(void);
};
foo::foo(int i) { bar = i; }
foo::~foo(void) { return; }
baz::baz(void) : foo(1) { return; }
baz::~baz(void) { return; }
quux::quux(void) : foo(2), baz() { return; }
quux::~quux(void) { return; }
baz b1;
std::auto_ptr<foo> b2(new baz);
quux q1;
std::auto_ptr<foo> q2(new quux);
Run Code Online (Sandbox Code Playgroud)
结果:
foo,baz并quux指向相应的主管删除 dtor.b1和b2由构成baz() 主管,它调用foo(1) 在充电q1和q2由构成quux() 主管,其落在foo(2) 在充电和baz() 未在充电用的指针foo它前面构造的对象q2被~auto_ptr() 充电破坏,这称为虚拟dtor ~quux() 充电删除,其中称为~baz() 非充电,~foo() 负责和operator delete.q1被破坏的~quux() 主管,要求~baz() 未主管和~foo() 主管b2被~auto_ptr() 充电破坏,它调用虚拟dtor ~baz() 充电删除,调用~foo() 负责和operator deleteb1被破坏~baz() 的负责,这就要求~foo() 主管任何人获得quux将使用其未主管构造函数和析构函数,并就创建的责任foo对象.
原则上,对于没有虚拟基础的类,从不需要非负责变体; 在这种情况下,有时将负责变体称为统一变量,和/或用于充电和不负责的符号别名为单个实现.