Déclaration de variables de type abstrait en C ++ [duplicate]

Sep 08 2020

Je voudrais définir une classe générale avec des fonctions et des classes imbriquées avec des fonctions virtuelles:

class c_foo {
    public:
        class c_subfoo {
            public:
                virtual int do_subfoo(void) = 0;
               
        };

        int do_foo(void);
};

La fonction c_foo :: do_foo () appellerait des fonctions dans la classe imbriquée c_foo :: c_subfoo :

int c_foo::do_foo(void) {
    c_subfoo subfoo;
    subfoo.do_subfoo();
    return 0;
};

Cependant, je ne peux pas déclarer la variable 'subfoo' comme étant du type abstrait 'c_foo :: c_subfoo' car c_foo :: c_subfoo :: do_subfoo est une fonction virtuelle pure .

Comment définir c_foo :: do_foo () , qui est toujours le même pour toutes les classes dérivées et qui appelle les fonctions c_foo :: c_subfoo , sans définir ces fonctions c_foo :: c_subfoo , qui sont différentes dans chaque classe dérivée?

Réponses

2 StPiere Sep 08 2020 at 15:49

La fonction virtuelle pure dit essentiellement: vous devez remplacer cette fonction. Et le remplacement signifie que vous devez dériver de c_subfoo et fournir une implémentation différente. Et cela signifie que vous ne pouvez pas instancier directement l'objet de c_subfoo.

Cela vous laisse donc différentes options:

1. utilisez un pointeur / une référence à un sous-sous-champ, par exemple.

c_subfoo* subfoo = somefactory::create_some_sub_subfoo();

subfoo->do_subfoo(); // now use virtual dispatch 

(of course, you would rather use smart pointers instead of raw pointers)

ou

  1. n'utilisez pas de pur virtuel

ou

  1. peut-être que vous pourriez rendre ces fonctions statiques, si elles n'ont pas besoin d'un objet pour fonctionner

ou

4.peut-être que vous pourriez utiliser le polymorphisme statique (comme CRTP )

template <typename SubFoo>
class c_foo : public SubFoo
{
...
   void do_foo()
   {
      ...
      SubFoo::do_subfoo();
      ...
   }
};

class c_subfoo : public c_foo<c_subfoo>
{
...
   void do_subfoo()
   {...}
}

En guise de remarque concernant votre question:

si une classe est imbriquée ou non ne joue aucun rôle dans ce cas. Cela affecte uniquement la visibilité / l'espace de noms de la classe interne, mais pas son comportement virtuel (ou purement virtuel).