C ++如何确保在使用虚拟继承时它调用继承而不是基函数
Posted
技术标签:
【中文标题】C ++如何确保在使用虚拟继承时它调用继承而不是基函数【英文标题】:C++ how to ensure when using virtual inheritance that it calls the inherited and not the base function 【发布时间】:2012-03-23 12:14:20 【问题描述】:我是 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;
;
最终的结果是将移动设置为空,而不是“摇滚”。
在此先感谢您提供正确方向的任何指示。这个让我很困惑。
-维多利亚
【问题讨论】:
见:***.com/questions/274626/… 为什么要使用虚拟继承?我看不到任何需要虚拟继承bout
的定义应该在类之外。符合标准的编译器将拒绝此实现。
【参考方案1】:
您不能将动态绑定与复制传递的参数一起使用。您必须传递引用 (Player&
) 或 const 引用 (Player const&
) 或指针 (Player*
) 或指向 const (Player const*
) 的指针。
示例:如果您实例化 Avalanche
并将其传递给接收 Player
的对象,则会发生这种情况:
C++ 看到获得Player
的签名,因此它将使用带有签名的默认复制构造函数创建对象的本地副本:Player::Player(Player const&)
。这个可以用你的Avalanche
参数调用,因为它是从Player
继承的公开。尝试隐藏Player
的复制构造函数,以了解发生了什么。
请随时指出您无法理解的事情。
【讨论】:
Player const*
不是 const 指针,它是指向 const Player 的指针。
常数不是细节。这很重要。
@LuchianGrigore:细节是语言。我完全同意 const 不是一个细节,而且 const 指针与指向 const 的指针完全不同。但请注意模式:“const 引用”是明确的,因为 Foo& const
根本没有意义(因为 const 是隐含的)。在谈论指针时,相同的表述意味着不同的东西。我猜这只是注意力不集中。
两者都不是模棱两可的。 “在谈论指针时,相同的表述意味着不同的东西”不是真的,const
的位置是完全定义的。
@LuchianGrigore:我相信我们正在谈论彼此。我在谈论将Foo const&
作为“常量引用”来谈论是多么普遍。虽然相同的语言模式应用于指针,而不是引用“const 指针”(与“指向 const 的指针”相对)实际上并不意味着 Foo const*
而是 Foo* const
。这一点,再加上中午注意力不集中,导致我写了“const 指针”,而我实际上的意思是“指向 const 的指针”:)【参考方案2】:
您将Player
对象传递给bout
,因此您没有利用多态性。
你应该传递指针或引用:
Player bout(Player*, Player*);
//or
Player bout(Player&, Player&);
请注意,在您的版本中,如果您将 Avalanche
对象传递给方法,您将遇到对象切片(查找)。
【讨论】:
只有当他们可以是nullptr
。如果没有,参考文献会更好。
感谢关于对象切片的提示,我确实遇到了这个问题。【参考方案3】:
当您调用Tournament::bout
时,您从传入的Avalanche
对象构造了两个新的Player
对象。
Player
构造函数不知道它正在复制/移动的对象的 Avalanche
部分,因此只复制 Player
部分。
p1
和 p2
是 Player
s,因此它们的行为类似于 Player
s,而不是 Avalanche
s。
如果您不想构造新的Player
对象,则通过引用传递参数:
Player& Tournament::bout (Player& p1, Player& p2)
p1.setMove();
p2.setMove();
return p1;
【讨论】:
以上是关于C ++如何确保在使用虚拟继承时它调用继承而不是基函数的主要内容,如果未能解决你的问题,请参考以下文章