new带有虚函数的对象数组,调用方法时崩溃
抽象的基类
class base
{
public:
base(){}
virtual ~base(){}
virtual void close() = 0;
};
派生类:
class derive:public base
{
public:
derive(){}
virtual ~derive(){}
virtual void close() override
{
printf("derive::close\n");
}
private:
uint32_t mDevice;
};
调用代码:
int main(int argc,char** argv)
{
base * ptr = new derive[2];
ptr[0].close();
ptr[1].close();
return 0;
}
第一个close能成功调用,调用第二个close,程序崩溃。
把 派生类的成员 mDevice 注释掉就不会崩溃了。
把 基类和派生类的 虚函数 去掉,也不会崩溃。
所以怀疑是不是这样生成对象数组,虚函数指针有什么问题?
请哪位明白的解释一下,谢谢。
new derive[2]
是动态创建derive对象数组,数组里每个元素是derive类型
你把这个数组的首地址赋给基类指针ptr
,然后你试图把这个数组当作基类对象数组来访问。显然这里基类和派生类的大小是不一样的,所以当你把这个数组当着基类对象数组来访问时,除了第一个元素地址是对的,其他元素地址就错位了(因为基类和派生类大小不一样)
你应该定义基类指针数组来存储指向派生类的指针
base *ptr[5];
for (int i = 0; i < 5; i++)
ptr[i] = new derive;
for (int i = 0; i < 5; i++)
ptr[i]->close();
或
derive *d = new derive[5];
base *ptr[5];
for (int i = 0; i < 5; i++)
ptr[i] = &d[i];
for (int i = 0; i < 5; i++)
ptr[i]->close();
做了如下尝试:
base * ptr = NULL;
derive *dd = new derive[2];
ptr = dd;
cout << &ptr[0] << endl;
cout << &ptr[1] << endl;
cout << &dd[0] << endl;
cout << &dd[1] << endl;
程序输出如下
0x76196c
0x761970
0x76196c
0x761974
基类指针与派生类指针差了4,正好是一个指针长度。
不要对数组是使用多态