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

C++ how to ensure when using virtual inheritance that it calls the inherited and not the base function

本文关键字:继承 调用 函数 基函数 虚拟 何确保 确保 C++      更新时间:2023-10-16

我是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;
    }
};

这样做的结果是将移动设置为零,而不是"摇滚"。

提前感谢您为我们提供正确的指导。这个让我很为难。

-维多利亚

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

示例:如果实例化一个Avalanche并将其传递给接收Player的对象,则会发生以下情况:

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

请随意指出你无法理解的事情。

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

您应该通过指针或引用传递:

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

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

调用Tournament::bout时,从传入的Avalanche对象构造两个新的Player对象。

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

p1p2Player s,因此它们的作用类似于Player s,而不是Avalanche s。

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

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