246 votes

Déclaration directe de types/classes imbriqués en C++.

J'ai récemment été coincé dans une situation comme celle-ci :

class A
{
public:
    typedef struct/class {...} B;
...
    C::D *someField;
}

class C
{
public:
    typedef struct/class {...} D;
...
    A::B *someField;
}

En général, vous pouvez déclarer un nom de classe :

class A;

Mais vous ne pouvez pas déclarer en avance un type imbriqué, ce qui suit provoque une erreur de compilation.

class C::D;

Des idées ?

6 votes

Pourquoi avez-vous besoin de cela ? Notez que vous pouvez déclarer en avant si c'est un membre de la même classe que celle qui est définie : class X { class Y ; Y *a ; } ; class X::Y { } ;

1 votes

Cette solution a fonctionné pour moi (namespace C { class D ; } ;): stackoverflow.com/questions/22389784/

0 votes

J'ai trouvé une solution enlace

0voto

chtz Points 6357

Il s'agirait d'une solution de contournement (du moins pour le problème décrit dans la question - et non pour le problème réel, c'est-à-dire lorsqu'on ne contrôle pas la définition de l'option C ) :

class C_base {
public:
    class D { }; // definition of C::D
    // can also just be forward declared, if it needs members of A or A::B
};
class A {
public:
    class B { };
    C_base::D *someField; // need to call it C_base::D here
};
class C : public C_base { // inherits C_base::D
public:
    // Danger: Do not redeclare class D here!!
    // Depending on your compiler flags, you may not even get a warning
    // class D { };
    A::B *someField;
};

int main() {
    A a;
    C::D * test = a.someField; // here it can be called C::D
}

-1voto

lixi Points 71

Cela peut être fait en avant de déclarer la classe externe comme un espace de nom .

Échantillon : Nous devons utiliser une classe imbriquée others::A::Nested dans others_a.h, ce qui est hors de notre contrôle.

autres_a.h

namespace others {
struct A {
    struct Nested {
        Nested(int i) :i(i) {}
        int i{};
        void print() const { std::cout << i << std::endl; }
    };
};
}

ma_classe.h

#ifndef MY_CLASS_CPP
// A is actually a class
namespace others { namespace A { class Nested; } }
#endif

class MyClass {
public:
    MyClass(int i);
    ~MyClass();
    void print() const;
private:
    std::unique_ptr<others::A::Nested> _aNested;
};

ma_classe.cpp

#include "others_a.h"
#define MY_CLASS_CPP // Must before include my_class.h
#include "my_class.h"

MyClass::MyClass(int i) :
    _aNested(std::make_unique<others::A::Nested>(i)) {}
MyClass::~MyClass() {}
void MyClass::print() const {
    _aNested->print();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X