为什么派生类不能在数组中工作?(C++)

3 c++ arrays polymorphism inheritance class

我用函数move创建了一个名为vir的类:

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     void move(){}
};
Run Code Online (Sandbox Code Playgroud)

(它派生自一个带有变量int x,int y和char sym的类)我从中派生了一个类,称为subvir:

class subvir:public vir
{
public:
     subvir(int a,int b,char s){x=a;y=b;sym=s;}
     void move();
};
subvir::move()
{
     x++;
     return;
}
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个vir数组,并将一个子文件放入其中

subvir sv1(0,0,'Q');
vir vir_RA[1]={sv1};
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用sv1.move()时:

vir_RA [0] .move();

它使用vir move({})而不是subvir move({x ++}).我试过让sv1成为vir和vir_RA成为vir,并且它有效,并且当我将它们制作为subvir时它也有效,但我需要它们不同.我试着让vir :: move()成为一个纯虚拟的,但后来我得到一个证明数组的错误.当我从数组中使用它时,有谁知道我怎么能使move()工作?

rlb*_*ond 8

您遇到了一个名为切片的问题.使用指针数组,或Boost.ptr_container之类的东西.

  • @jmucchiello:切片肯定发生在这里 - vir_RA的第一个元素将使用编译器为类型vir的自动生成的复制构造函数从sv1进行复制初始化(实际上是复制构造). (2认同)

dir*_*tly 8

基类必须有virtual函数来获得你想要的东西,使这些纯函数会产生一个抽象的基类 - 你无法实例化的东西.但是,您仍然可以创建指向抽象基类的指针/引用,并将派生类对象分配给它们.您的基类最好表示为:

class vir
{
public:
     vir(int a,int b,char s){x=a;y=b;sym=s;}
     virtual void move(){}
};
Run Code Online (Sandbox Code Playgroud)

这使得派生类也是move虚拟的.但是,您的move定义缺少返回值,无法编译.尝试:

void subvir::move()
{
     x++;
     return;
}
Run Code Online (Sandbox Code Playgroud)

请注意,您需要指针(如其他答案中所述)或对派生类的引用以使动态绑定起作用.因此,vir使用基类指针数组而不是对象数组:

vir* v[ 2 ] = { new subvir(0, 0, 'Q'), new subvir(10, -10, 'P') };
Run Code Online (Sandbox Code Playgroud)

您还应该阅读C++ FAQ Lite的以下部分:


Sco*_*ski 5

在这种情况下,您需要一个指针数组,而不是一个实例数组.使用vir*[]而不是vir []


jmu*_*llo 5

两件事情.数组是vir的数组,所以当然它使用了vir :: move.move()不是虚方法.

但更重要的是切片.您不能将子类放入数组中.如果sizeof vir!= sizeof subvir,则阵列将无法正确排列.目前它们的大小相同.但如果他们不这样做会发生什么.