Le *_*anh 7 c++ arrays polymorphism virtual inheritance
class Base1
{
private:
int testInput;
public:
Base1();
virtual int GetRow(void) = 0;
};
Base1::Base1()
{
testInput = 0;
}
class table : public Base1
{
private:
int row;
public:
table();
virtual int GetRow(void);
};
table::table()
{
//Contructor
row = 5;
}
int table::GetRow()
{
return row;
}
int main ()
{
Base1* pBase = new table[3];
pBase[0].GetRow();
pBase[1].GetRow(); //when i get to this line, the compiler keep saying access
// violation.
pBase[2].GetRow();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个3表类的数组.要求是我必须使用Base对象来做到这一点.
Base1 * pBase = new table[3];
Run Code Online (Sandbox Code Playgroud)
看起来很好.但是当我试图访问每个表时,编译器说它是访问冲突.我不知道这段代码有什么问题.我正在使用Visual Studio 2010.
NPE*_*NPE 14
在C++中,多态和数组不会混合.
由于通常派生类的大小与基类的大小不同,因此多态和指针算法不能很好地一起使用.由于数组访问涉及指针运算,因此表达式pBase[1] 不能按预期工作.
一种可能性是拥有指向对象的指针数组,甚至可能是智能指针以简化内存管理.但是不要忘记在中定义一个虚拟析构函数Base1.
您收到错误是因为数组是静态类型的Base1.这意味着这一行:
pBase[1].GetRow();
Run Code Online (Sandbox Code Playgroud)
添加Base1以字节为单位的大小pBase并将其解释为另一个Base1对象的开头,但这实际上将某个位置指向第一个table实例的中间位置.
如果需要多态实例数组,则必须std::vector通过指针(或最好是某种形式的智能指针)将它们存储在数组中(或最好存储在a中).
阿格纽的回应非常到位。让我再解释一下。Base1通过扩充您的代码,我打印出 a和 a对象的大小table以及table由运算符创建的三个对象的地址new:
A Base1 object is 8 bytes
A table object is 12 bytes
A table object is being constructed at 0x002977C0
A table object is being constructed at 0x002977CC
A table object is being constructed at 0x002977D8
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这些对象在内存中彼此间隔 12 个字节。
现在,让我们打印出 pBase[0]、pBase[1] 和 pBase[2] 给出的地址:
pBase[0] is at 0x002977C0
pBase[1] is at 0x002977C8
pBase[2] is at 0x002977D0
Run Code Online (Sandbox Code Playgroud)
现在看看会发生什么:我们返回的指针间隔 8 个字节。Base1这是因为指针算术是在类型为 8 字节长的指针上完成的,Base1编译器所做的就是将其转换pBase[n]为pBase + (n * sizeof(Base1)).
现在您应该能够准确理解为什么第一个 GetRow()有效以及为什么在第二个上崩溃。