C ++如何确保在使用虚拟继承时调用它继承而不是基本函数

时间:2012-03-23 12:14:21

标签: c++ inheritance polymorphism

我对C ++很陌生,非常感谢任何帮助。我有这个赋予类和继承的任务。我的理解是我可以在基类中编写一个虚函数,该函数被继承类中的同名函数覆盖。当我调用任何继承的类时,这可以正常工作,但是当我将它们插入到编写的函数中以接收基类时,即使它接收的对象来自继承的类,它也会从继承的类中调用初始化函数,但是仅从基类中起作用。这是我的代码的缩短版本:

基类:

#ifndef PLAYER_CPP
#define PLAYER_CPP
class Player 
{    
protected:
    string playerThrow;
public:
    //function that sets player throw
    void virtual setMove();
    string performMove() {return(playerThrow);}
};
#endif

继承类:

class Avalanche: virtual public Player
{
public:
    Avalanche();    
    //set specific move for class
    void setMove() 
    {
        //always plays rock
        playerThrow = "rock";
    }
};

//initializer, inherit from player, set new name
Avalanche::Avalanche() : Player()
{   
    //initialize name string
    string newName;
    //set name
    newName = "Avalanche Player";
    //sets name in player class
    name = newName;
}

我是如何尝试使用它的:

class Tournament
{
public:
    Tournament();
    Player bout(Player, Player);
    Player Tournament::bout (Player p1, Player p2)
    {
        p1.setMove();
        p2.setMove();
        return p1;
    }
};

这最终会让行动变为空虚,而不是“摇滚”。

提前感谢任何指向正确的方向。这个让我难过。

-Victoria

3 个答案:

答案 0 :(得分:3)

您不能对复制传递的参数使用动态绑定。您必须传递引用(Player&)或const引用(Player const&)或指针(Player*)或指向const(Player const*)的指针。

示例:如果您实例化Avalanche并将其传递给接收Player的内容,则会发生以下情况:

C ++看到获得Player的签名,因此它将使用带有签名的默认复制构造函数Player::Player(Player const&)创建对象的本地副本。可以使用Avalanche参数调用此 ,因为它是从Player公开继承的 。尝试隐藏Player的复制构造函数,以了解发生了什么。

请随意指出一些无法理解的内容。

答案 1 :(得分:0)

您将Player个对象传递给bout,因此您没有利用多态性。

你应该传递指针或参考:

Player bout(Player*, Player*);
//or
Player bout(Player&, Player&);

请注意,在您的版本中,如果您将Avalanche个对象传递给该方法,则会遇到对象切片(请查看)。

答案 2 :(得分:0)

当您致电Tournament::bout时,您会从传入的Player个对象中构建两个新的Avalanche个对象。

Player构造函数不知道它正在复制/移动的对象的Avalanche部分,因此只复制Player部分。

p1p2Player个,因此它们的行为类似于Player s,而不是Avalanche s。

如果您不想构造新的Player个对象,请通过引用传递参数:

Player& Tournament::bout (Player& p1, Player& p2)
{
    p1.setMove();
    p2.setMove();
    return p1;
}