Mar*_*tin 3 c++ arrays polymorphism inheritance
当我分配单个对象时,此代码工作正常.当我尝试添加数组语法时,会出现段错误.为什么是这样?我的目标是向外界隐瞒类c在内部使用b对象的事实.我已将程序发布到键盘供您使用.
#include <iostream>
using namespace std;
// file 1
class a
{
public:
virtual void m() { }
virtual ~a() { }
};
// file 2
class b : public a
{
int x;
public:
void m() { cout << "b!\n"; }
};
// file 3
class c : public a
{
a *s;
public:
// PROBLEMATIC SECTION
c() { s = new b[10]; } // s = new b;
void m() { for(int i = 0; i < 10; i++) s[i].m(); } // s->m();
~c() { delete[] s; } // delete s;
// END PROBLEMATIC SECTION
};
// file 4
int main(void)
{
c o;
o.m();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
创建10的阵列b与的new,然后分配给它的地址到a*被找麻烦.
不要多态地处理数组.
有关更多信息,请参阅ARR39-CPP.不要把阵列多态,在部分06.阵列和STL(ARR)的的CERT C++安全编码标准.
一个问题是表达式s[i]使用指针算法来计算所需对象的地址.由于s被定义为指针a,结果对于as 的数组是正确的,对于s 的数组是不正确b的.继承提供的动态绑定仅适用于方法,没有别的(例如,没有虚拟数据成员,没有虚拟sizeof).因此,当调用方法时s[i].m(),this指针被设置为数组中的i第th个a对象.但是因为实际上数组是bs中的一个,它最终(有时)指向对象中间的某个地方并且你得到一个段错误(可能是当程序试图访问对象的vtable时).您可以通过虚拟化和重载来纠正问题operator[]().(尽管如此,我并没有考虑它是否真的有效.)
另一个问题是delete在析构函数中,出于类似的原因.您也可以虚拟化和重载它.(再一次,只是一个随意的想法突然出现在我脑海里.可能不起作用.)
当然,铸造(如其他人所建议的)也会起作用.
| 归档时间: |
|
| 查看次数: |
2009 次 |
| 最近记录: |