我创建了一个名为vir的类,其函数为:
class vir
{
public:
vir(int a,int b,char s){x=a;y=b;sym=s;}
void move(){}
};
(它派生自一个带有变量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;
}
然后我创建了一个vir数组,并将一个子文件放入其中
subvir sv1(0,0,'Q');
vir vir_RA[1]={sv1};
但是当我尝试使用sv1.move()时:
vir_RA [0] .move();
它使用vir move({})而不是subvir move({x ++})。我试过让sv1成为vir和vir_RA成为vir,并且它有效,并且当我将它们制作为subvir时它也有效,但我需要它们不同。我尝试使vir :: move()成为一个纯虚拟的,但后来我得到了一个证明数组的错误。当我从数组中使用它时,有谁知道我怎么能让move()工作?
答案 0 :(得分:8)
您遇到了一个名为slicing的问题。使用指针数组,或类似Boost.ptr_container。
答案 1 :(得分:8)
基类必须具有virtual
函数才能得到你想要的东西,使这些纯函数导致抽象基类 - 你无法实例化的东西。但是,您仍然可以创建指向抽象基类的指针/引用,并将派生类对象分配给它们。您的基类最好表示为:
class vir
{
public:
vir(int a,int b,char s){x=a;y=b;sym=s;}
virtual void move(){}
};
这使得派生类的move
也是虚拟的。但是,您的move
定义缺少返回值,无法编译。尝试:
void subvir::move()
{
x++;
return;
}
请注意,您需要指针(如其他答案中所述)或对派生类的引用以使动态绑定起作用。因此,使用基类指针数组而不是vir
个对象数组:
vir* v[ 2 ] = { new subvir(0, 0, 'Q'), new subvir(10, -10, 'P') };
你也应该f 请阅读C ++ FAQ Lite的以下部分:
答案 2 :(得分:5)
在这种情况下,您需要一个指针数组,而不是一个实例数组。使用vir * []代替vir []
答案 3 :(得分:5)
两件事。数组是vir的数组,所以当然它使用了vir :: move。 move()不是虚方法。
但更重要的是切片。您不能将子类放入数组中。如果sizeof vir!= sizeof subvir,则阵列将无法正确排列。目前它们的大小相同。但如果他们不这样做会发生什么。
答案 4 :(得分:2)
是的,基本上编译器不允许在数组中使用子类,因为 对于类型大小,数组被紧密初始化,并且子类型倾向于 要比父母大,如果可以的话会导致问题 使用子类型值初始化数组。 真正发生的是编译器首先分配数组N * size(base_type)字节。 然后它复制每个初始化的大小(base_type)字节 对象。如果他们是不同的类型,他们会被截断, 你的代码可能会发生奇怪的事情。
答案 5 :(得分:1)
让我巩固以前的答案。
这里实际上有两个问题。一个是切片。您正在使用子文件的副本初始化一组virs。在这种情况下,编译器将vir部分从subvir中切出并将其复制到数组中,因此你真的只能获得vir对象。现在在你的特殊情况下,subvir没有超出vir的额外数据成员,因此切片有点退化,vir对象看起来很像subvir。然而,vir和subvir是不同的类,并且数组中的对象最终是vir对象而不是伪装成vir的subvir对象。实际上,即使两者具有相同的数据成员,两者之间的差异实际上也会表现出来的一种方式是,如果vir具有由子记录重载的虚函数。在这种情况下,数组中对象中的vtable指针将指向vir的vtable,而不是subvir。当然,如果subvir包含在vir中找不到的其他数据成员,那将更加明确。
第二个问题是多态性。在使用时(对move()的调用),编译器认为你正在调用类型为vir的对象的move()方法(因为数组是virs的数组)。 (编译器当然是正确的,因为切片,在这种情况下可能会退化。)如果它实际上是你想要的subvir对象,你可以通过移动来调用subvir :: move()(虚拟的虚拟。
要获得所需的行为,您可以使用指针数组(但之后您将直接在sv1上运行,而不是它的副本,除非您首先创建副本并使用指向副本的指针初始化数组)。