我对以下代码段和输出有一些理解问题.任何人都可以提供一个解释,主要是为什么test()按照输出中的方式工作.我正在使用MSCV 2008 C++编译器.
class AS
{
int a;
public:
AS():a(1){show();}
virtual void show() {cout<<a<<endl;}
void test() { cout<<"Calling show()"<<endl; this->show();}
};
class BS: virtual public AS
{
int b;
public:
BS():b(2){show();}
virtual void show() {cout<<b<<endl;}
void test() { cout<<"Calling show()"<<endl; this->show();}
};
class CS:public virtual AS
{
int c;
public:
CS():c(3){show();}
virtual void show() {cout<<c<<endl;}
void test() { cout<<"Calling show()"<<endl; this->show();}
};
class DS:BS, public CS
{
int d;
public:
DS():d(4){show();}
virtual void show() {cout<<d<<endl;}
void test() { cout<<"Calling show()"<<endl; this->show();}
};
int main()
{
cout<<"Class Sizes:"<<endl;
cout<<sizeof(AS)<<endl;
cout<<sizeof(BS)<<endl;
cout<<sizeof(CS)<<endl;
cout<<sizeof(DS)<<endl;
AS* aa = new DS();
aa->test();
aa->show();
delete aa;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是: -
Class Sizes:
8
20
20
32
1
2
3
4
Calling show()
4
4
Run Code Online (Sandbox Code Playgroud)
删除aa时出现断点异常; 为什么?
无论何时调用delete指向派生类对象的基类指针,基类都必须具有virtual析构函数.如果不这样做会导致未定义的行为.
所以,你的类AS需要提供一个virtual析构函数:
class AS
{
public:
virtual ~AS(){}
};
Run Code Online (Sandbox Code Playgroud)
您的困惑似乎是virtual通过构造函数和析构函数调用的函数的输出.
该类型的this构造函数和析构函数中是型谁的构造函数/析构函数被调用的类.因此virtual,构造函数和析构函数的任何函数调用都不会显示您通常期望的虚拟函数的动态调度行为.而是调用该特定类的函数.
至于size类对象.你不应该假设尺寸是特定的.编译器可以自由添加填充字节,这可能会增加甚至非多态类的大小.对于多态类,通常大多数实现将向类对象添加虚拟指针以实现动态分派机制,从而增加对象大小.请注意,这完全取决于实现.
因此,总是只使用大小,sizeof而不是依赖它是任何具体的.
| 归档时间: |
|
| 查看次数: |
147 次 |
| 最近记录: |