2017-01-10 5 views
1

J'ai une classe d'interface - IAnimal et 2 classes dérivées - Tcat et Tdog. Je veux que Tcat et Tdog héritent de la fonction Eat, cependant, je veux que Tcat puisse avoir 2 paramètres et que Tdog ait les paramètres hérités. Est-ce possible?Peut-on remplacer les fonctions virtuelles pures de la classe héritée?

/// Pure virtual - to ensure all inherited animals have eat and sleep 
class IAnimal 
{ 
public: 
    virtual ~IAnimal() {} 
    virtual bool Eat(int _i_food) = 0; 
    virtual bool Sleep(int _i_time) = 0; 
}; 

class TCat : public IAnimal 
{ 
public: 
    bool Eat(int _i_food, int _i_amount); // can we override interface pure virtual from inherited class? 
    bool Sleep(int _i_time); 
}; 

class TDog : public IAnimal 
{ 
public: 
    bool Eat(int _i_food); 
    bool Sleep(int _i_time); 
}; 
+5

D'abord 'TCat' ne compilera pas parce que le contrat est ici que vous devez mettre en œuvre' bool Eat (int) ', d'autre part si vous définissez une nouvelle fonction qui ne correspond pas à la signature pure de la fonction virtuelle de la classe de base, alors cela ne surcharge pas mais surcharge – EdChum

+1

Google le principe de substitution de Liskov. Ensuite, examinez votre code et voyez pourquoi ce que vous faites ne parvient pas à le respecter. – StoryTeller

+1

@EdChum sans déclaration explicite de 'using ', c'est cacher, pas surcharger. – Quentin

Répondre

0

Pas

Ce n'est pas possible. Et cela n'aurait aucun sens non plus, car si ces fonctions ont une signature différente, vous ne pourrez pas les appeler via l'interface. Que devrait-il se passer si vous passez un paramètre à travers l'interface et que l'instance réelle en nécessite deux? Ce que vous pouvez peut remplacer celui que vous avez à, puis ajouter une méthode supplémentaire avec deux paramètres. Mais vous ne serez pas en mesure d'appeler le nouveau via l'interface.

0

Vous devez fournir une implémentation de toutes les fonctions virtuelles pures. Vous pouvez remplacer la fonction Eat(int _i_food) mais il ne sera pas possible d'invoquer la version surchargée en utilisant le pointeur vers la classe de base.

0

Votre problème est que la méthode Eat dans TCat n'est pas une substitution de la méthode dans sa classe de base mais une surcharge, et qu'elle "cache" la méthode de la classe de base.

Voir cette question:

Why does a virtual function get hidden?

2

Non Signature d'une méthode virtual ne peut pas être modifié. Pas même avec les paramètres par défaut. La seule exception est covariance, où le type de retour peut être différent. Avec C++ 11, la règle de base est de mettre override spécificateur après la méthode supposée virtual (pur ou non). S'il ne compile pas, alors quelque chose ne va pas. Dans votre exemple de code, suivant échouera compiler:

bool Eat(int _i_food, int _i_amount) override; // error