2013-07-03 1 views
3

Je pensais utiliser le constructeur protégé , mais il ne pouvait pas complètement résoudre le problème puisque la classe qui en héritait serait capable d'instancier la classe de base.Une classe abstraite peut-elle être implémentée sans fonctions virtuelles pures en C++?

Comme pour constructeur privé, les classes dérivées aussi ne seraient pas instanciées.

Ainsi, toute technique appropriée serait appréciée.

+7

S'il n'y a pas au moins une fonction virtuelle pure, alors ce n'est pas une classe abstraite. –

+4

* Qu'essayez-vous réellement de faire? * – Beta

+0

Ce que j'essayais de faire était d'imiter l'effet que la fonction virtuelle pure a dans la classe sans avoir la fonction virtuelle virtuelle dans la classe! – Sankalp

Répondre

3

On ne sait pas ce que vous demandez vraiment. Alors, laissez-moi essayez d'effacer certains points:

fonctions virtuelles pures peuvent avoir des définitions

Si votre préoccupation est que vous voulez fournir des définitions pour toutes les fonctions virtuelles dans votre base, vous pouvez fournir les définitions pour le virtuel pur fonction s, et ils seront disponibles pour l'envoi statique.

accorde l'accès protégé à votre sous-objet de base, et non pas à tous les cas de base

Il y a une idée fausse très répandue que protected permet à un type dérivé particulier l'accès à une instance de base. Ce n'est pas vrai. Le mot clé protected accorde l'accès au sous-objet base dans le type dérivé.

class base { 
protected: base() {} 
}; 
class derived : public base { 
    derived() : base() {   // fine our subobject 
     base b;     // error, `b` is not your subobject 
    } 
}; 
+0

@Sankalp: Cela ne dit pas ce que vous essayez de faire, seulement ce que votre approche pour y arriver était. * Qu'est-ce que vous voulez faire que vous avez besoin de fausses classes abstraites? * –

1

La définition d'une classe abstraite est celui qui a au moins une fonction virtuelle pure (virtual function-signature = 0; Vous ne pouvez pas créer une classe abstraite sans eux.

+0

Est-ce que vous êtes sûr? –

+0

@ g-makulik - c'est la définition dans le langage C++. –

+0

@PeteBecker Mais une classe abstraite est juste un concept (une classe non istantiatable). Regardez les concepts de polymorphisme statique et vous verrez que vous pouvez ** créer ** des classes abstraites sans utiliser de fonctions virtuelles pures. –

1

une classe abstraite peut être mis en œuvre sans fonctions virtuelles pures en C++?

Si vous choisissez le point de vue de Static Polymorphism, vous pouvez le faire!

Une classe de base abstraite manquerait simplement une implémentation de méthode par défaut pour une méthode d'interface de la classe dérivée.

En outre, vous pouvez utiliser des constructeurs protégés pour ces modèles de classe de base CRTP, pour exiger l'héritage pour l'instanciation.

MISE À JOUR:
J'ai trouvé un beau diaporama, qui explique static vs dynamic polymorphism complètement. Chaque technique a ses avantages et ses inconvénients et certains domaines d'utilisation, en plus vous pouvez mélanger les deux techniques (judicieusement bien sûr).

Pour élaborer un peu, je vais vous donner un exemple:

template<class Derived> 
class AbstractBase 
{ 
public: 
    // Equivalent for a pure virtual function 
    void foo() 
    { 
     // static_cast<> enforces an 'Is a' relation from Derived to AbstractBase 
     static_cast<Derived*>(this)->fooImpl(); 
    } 

    // Equivalent for simple virtual function (overidable from Derived) 
    void bar() 
    { 
     static_cast<Derived*>(this)->barImpl(); 
    } 

    // Default implementation for any call to bar() 
    void barImpl() 
    { 
    } 

protected: 
    AbstractBase() {} 
}; 

// Compilation will fail, since ConcreteClass1 doesn't provide 
// a declaration for fooImpl() 
class ConcreteClass1 
: public AbstractBase<ConcreteClass1> 
{ 
} 


// Compiles fine 
class ConcreteClass2 
: public AbstractBase<ConcreteClass2> 
{ 
public: 

    void fooImpl() 
    { 
     // Concrete implementation ... 
    } 
} 

L'exemple suivant montre que le modèle introduit applique au-dessus d'un « Est-ce une » relation entre la classe abstraite et héritant classe (paramètre modèle)

class ConcreteClass3 
{ 
public: 
    void fooImpl() 
    { 
     // Concrete implementation ... 
    } 
} 

// Instantiation will fail, because 
// * the constructor is protected 
// * at least the static cast will fail 
AbstractBase<ConcreteClass3> instance; 
0

Je l'ai lu dans mon livre Un abstr La classe t est une classe conçue pour être utilisée spécifiquement comme classe de base. Une classe abstraite contient au moins une fonction virtuelle pure. Vous déclarez une fonction virtuelle pure en utilisant un spécificateur pur (= 0) dans la déclaration d'une fonction de membre virtuel dans la déclaration de classe.

Questions connexes