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;
}
我试图创建3个表类的数组。 要求是我必须使用的基本对象来做到这一点。
Base1 * pBase = new table[3];
看起来没什么问题。 但是,当我试图访问的每个表,编译器说,它的访问冲突。 我不知道自己做错了什么,此代码。 我使用Visual Studio 2010中虽然。
在C ++中,多态性和数组不要混用。
因为一般的派生类的大小是基类,多态和指针算法不很好地一起玩的大小不同。 由于阵列访问包括指针运算,表达式如pBase[1]
不正常工作。
一种可能性是具有指针数组到你的对象,甚至是智能指针,以简化内存管理。 但不要忘了在定义虚拟析构函数Base1
。
你得到的错误,因为该数组是静态类型到Base1
。 这意味着,这条线:
pBase[1].GetRow();
增加的规模Base1
字节到pBase
和将此解释为另一年初Base1
对象,但是这实际上指向某个地方进入第一中间table
实例。
如果需要的多态实例的阵列,则必须将它们存储阵列(或优选地在在std::vector
通过指针)(或优选某种形式的智能指针)。
阿格纽的反应是当场上。 让我来解释一下。 通过增加你的代码,我打印出的大小Base1
和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
正如可以看到的那些对象在存储器间隔开的12个字节彼此。
现在,让我们打印出的地址是PBASE [0],P基准[1]和PBASE [2]给出:
pBase[0] is at 0x002977C0
pBase[1] is at 0x002977C8
pBase[2] is at 0x002977D0
现在看看会发生什么:我们回到指针相隔8个字节。 这是因为指针算法上的指针,其类型为完成Base1
,自Base1
是8个字节渴望什么编译器是把pBase[n]
到pBase + (n * sizeof(Base1))
现在,你应该能够正确理解为什么第一个 GetRow()
的作品,为什么你崩溃第二。
您需要创建(用new
)所有这些数组元素,像这样做:
for(int i = 0; i < 3; ++i)
pBase[i] = new table();