2009-07-07 8 views
2

pour créer une instance d'une autre classe à partir d'une classe même si la classe que je veux avoir une instance de est déclarée en regard de la classe à partir de laquelle je crée une instance. Tout comme en C# et Java.est-ce possible en C++?

Merci

Répondre

1

Bien sûr. Vous avez juste besoin d'une déclaration avant. Quelque chose comme ça fonctionne très bien:

#include <iostream> 

class B; 

class A { 
public: 
    void hello(B &b); 
    void meow(); 
}; 

class B { 
public: 
    void hello(A &a); 
    void woof(); 
}; 

void A::hello(B &b) { b.woof(); } 
void A::meow() { std::cout << "Meow!" << std::endl; } 

void B::hello(A &a) { a.meow(); } 
void B::woof() { std::cout << "Woof!" << std::endl; } 

int main() { A a; B b; a.hello(b); b.hello(a); return 0; } 

La clé ici est que vous ne pouvez utiliser des pointeurs ou des références à une classe jusqu'à ce qu'il ait été complètement défini. Donc dans l'exemple que j'ai donné, la méthode hello() dans A peut être déclarée pour prendre une référence à B, même si nous n'avons pas défini B au point. Après la définition de B, cependant, la définition de la méthode A :: hello() est libre d'utiliser B à sa guise.

+0

hey cela a vraiment aidé! Merci –

+1

"vous ne pouvez utiliser des pointeurs ou des références à une classe que si elle a été entièrement définie". Autant que je sache, vous pouvez également passer des classes par la valeur vers et à partir des fonctions ... – SadSido

+0

Où est le prix de _deciphering_ cette question? – bobobobo

1

Je suppose que vous voulez dire faire quelque chose comme ceci:

class B; //Forward declaration 

class A 
{ 
    private: 
    B b; 
}; 


class B 
{ 

}; 

Ce n'est pas possible en C++ comme le compilateur a besoin de connaître le sizeof (B) lorsque la classe compilation A.

en tant que solution ce que vous pouvez faire est:

class B; //Forward declaration 

     class A 
     { 

      public: 
      A(); 
      ~A(); 

      private: 
      B* m_pB; //Store a pointer to B 

     }; 


     class B 
     { 

     }; 

A::A() 
{ 
    m_pB = new B; //Create an instance of B 
} 

A::~A() 
{ 
    delete m_pB; //Explictly deallocate the memory. 
    m_pB = NULL; 
} 
+0

oui je le sais. mais que faire si je veux accéder à une variable publique ou à une fonction de cette classe? –

+0

Mais le contraire (avec A juste en dessous de B) compilera bien. –

+0

@maxx: Cela ne sera pas possible car le compilateur sait juste qu'il y a quelque chose appelé la classe B utilisant la déclaration forward, mais il n'a aucune idée de son contenu. – Naveen

0

une fois que vous en avant décla re B dans l'en-tête vous pouvez l'utiliser dans le fichier .cpp sans problème pour accéder aux variables et méthodes publiques.

+0

pouvez-vous s'il vous plaît me donner un exemple de travail C++. Merci –

2

Vous pouvez utiliser une déclaration directe dans certains cas, mais vous devrez utiliser le type complet chaque fois que vous en utiliserez réellement. Il pourrait être utile de préciser la question sur ce que vous voulez vraiment réaliser, car il pourrait y avoir des approches plus simples de votre problème (si l'ordre est important, cela pourrait indiquer une dépendance circulaire entre les classes A et B). bien).

class B; 
class A 
{ 
public: 
    A(B b, B* bp, B& br) : bp_(bp), br_(br) {} // ok, incomplete types can be used as argument types 
    B f() 
// { return B(); } // nok: cannot create objects of incomplete type 
    ; 
    B* f2() { return bp_; } // ok 
    B& f3() { return br_; }; // ok 
    void g() 
// { bp_->g(); br_.g(); } // nok: cannot call methods of an incomplete type 
    ; 
    void g(B const & b) 
// { b.g(); } // nok: cannot call methods of an incomplete type 
private: 
    B * bp_; // ok (also const version) 
    B & br_; // ok (also const version) 
// B b_; // nok: B must be a complete type here 
}; 
class B { // A is complete, any use is correct here 
    void g() {} 
}; 
// From here on, B is a complete type and can be used in any possible way 
B A::f() { 
    return B(); // ok, now B is complete 
} 
void A::g() { 
    br_.g(); // ok, B is complete here 
    bp_->g(); // ok, B is complete here 
} 
void A::g(B const & b) { 
    b.g(); 
} 
Questions connexes