Question

Est-il possible de transmettre-déclarer une classe imbriquée, utilisez-le comme type pour un béton (pointeur pas / référence) membre de données de la classe externe?

i.e..

class Outer;

class Outer::MaybeThisWay   // Error: Outer is undefined
{
};

class Outer
{
 MaybeThisWay x;

 class MaybeThatOtherWay;

 MaybeThatOtherWay y;   // Error: MaybeThatOtherWay is undefined
};
Était-ce utile?

La solution

Vous ne pouvez pas en avant-déclarer une classe imbriquée comme ça.

En fonction de ce que vous essayez de faire, vous pouvez peut-être utiliser un espace de noms plutôt que d'une classe sur la couche extérieure. Vous pouvez transférer-déclarer une telle classe aucun problème:

namespace Outer {
   struct Inner; 
};

Outer::Inner* sweets;  // Outer::Inner is incomplete so 
                       // I can only make a pointer to it

Si votre extérieur doit absolument être une classe, et vous ne peut-chausse-pied dans un espace de noms, alors vous aurez besoin pour être externe un type complet dans le contexte où vous déclarez avant intérieure.

class Outer
{
   class Inner;  // Inner forward-declared
};  // Outer is fully-defined now

Outer yes;  // Outer is complete, you can make instances of it
Outer::Inner* fun;  // Inner is incomplete, you can only make 
                    // pointers/references to it

class Outer::Inner 
{
};  // now Inner is fully-defined too

Outer::Inner win;  // Now I can make instances of Inner too

Autres conseils

Il n'y a aucun moyen de transmettre déclarer une classe imbriquée sans spécifier entièrement la classe contenant. Cette petite astuce corrige un peu le problème que

class Outer_Inner
{
};

class Outer
{
public:
   typedef Outer_Inner Inner;
};

Cela fonctionne pour moi dans ma convention de nommage Outer_Inner est pas un nom de classe valide, il est évident qu'il se réfère à une classe imbriquée.

Vous ne pouvez toujours pas déclarer avant la classe imbriquée comme ceci:

class Outer::Inner;

Mais au moins il peut être déclaré en avant avec:

class Outer_Inner;

Si vous ne voulez pas la façon dont Outer_Inner vous semble pourrait adopter une convention de nommage pour les classes imbriquées qui correspond mieux à vos goûts de. Outer__Inner, Outer_nested_Inner, etc.

Non, mais ce qui ne va pas avec

class Outer {
public:  //or protected or private
    class Inner {
    };

private:
    Inner foo;
};

Forward déclarant n'a pas de sens ici, à moins que je me manque quelque chose (ce qui est possible de voir que votre question fait défaut dans beaucoup de détails)

Rappelez-vous, si une classe est déclarée avant alors vous ne pouvez déclarer ou les références à des pointeurs vers un objet du type déclaré de l'avant. Vous ne pouvez rien faire d'autre avec elle, y compris l'accès aux membres de fonctions ou elle.

Si une classe a été déclarée avant (mais vous n'avez pas encore la définition complète), vous pouvez seulement déclarer un pointeur, car le compilateur ne connaît pas encore la taille de la classe (ni les noms de ses domaines ou méthodes).

Si vous déclarez un attribut de type MaybeThatOtherWay, pas une référence ni un pointeur, le compilateur doit connaître la définition complète de la classe pour déterminer la taille de la classe externe. Ainsi, vous ne pouvez pas utiliser avant la déclaration et ce genre de déclaration sur le terrain, que ce soit une classe imbriquée ou non.

Si vous avez juste besoin d'un type en tant que paramètre de fonction ou variable statique, il pourrait être fait du côté client. Par exemple, pour recevoir une notification d'événement dans extérieur:

Interface:

class Client {
public:
private:
    static void gotIt(int event);
    class Helper;
};

Mise en œuvre:

#include <outer.hpp>

class Client::Helper {
public:
    static void fromOuter(Outer::Inner const& inner) 
    { 
        gotIt(inner.event());
    }
};
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top