2012-03-23 74 views
1

我对C++非常陌生,非常感谢任何和所有的帮助。我有这个任务可以玩类和继承。我的理解是,我可以在基类中编写一个虚拟函数,它被继承类中的相同名称的函数覆盖。当我调用任何继承类时,这种方法很好,但是当我将它们插入一个写入基类的函数中时,即使它接收的对象来自继承类,它也会从继承类调用初始化器,但其他只能从基类中运行。这里是我的代码缩短版本: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

+1

参见:http://stackoverflow.com/questions/274626/what-is-the-slicing -problem-in-c – Mankarse 2012-03-23 12:17:22

+2

为什么使用虚拟测试?我看不到虚拟继承的任何需要 – softghost 2012-03-23 12:49:18

+0

'bout'的定义应该在类之外。符合编译器会拒绝这个实现。 – 2012-03-23 15:36:41

回答

3

不能使用动态与复制传递的参数结合。您必须通过引用(Player&)或const引用(Player const&)或指针(Player*)或指向const(Player const*)的指针。

例如:如果你初始化Avalanche并将它传递的东西,收到Player,出现这种情况:

C++看到的是得到一个Player签名,所以它会创建一个本地拷贝你的对象,使用带签名的默认拷贝构造函数:Player::Player(Player const&)。这可以被称为你的Avalanche论点,因为它是继承公开Player。尝试隐藏Player的复制构造函数,以了解发生了什么。

请随时指出那些对你来说不理解的事情。

+1

'Player const *'不是一个常量指针,它是一个指向const Player的指针。 – 2012-03-23 12:19:32

+0

@LuchianGrigore:它总是语言的细节。谢谢,修复它... – bitmask 2012-03-23 12:24:50

+0

恒常不是一个细节。这很重要。 – 2012-03-23 12:26:55

0

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

你应该通过指针或引用:

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

注意,在你的版本,如果你通过Avalanche对象的方法,你会碰到物体切片(看,最多)。

+1

只有当他们可以'nullptr'。如果不是,引用是更好的。 – 2012-03-23 12:20:18

+0

@CatPlusPlus权利,我编辑。 – 2012-03-23 12:21:15

+0

感谢您在对象切片上的提示,我确实遇到了这个问题。 – quipish 2012-03-23 13:14:33

0

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

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

p1p2Player S,所以他们像Player S,不Avalanche秒。

如果你不想来构建新的Player对象,然后按引用传递参数:

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