2009-07-07 13 views
2

インスタンスを作成したいクラスがインスタンスを作成しているクラスの次に宣言されていても、クラスから別のクラスのインスタンスを作成することができます。 C#とJavaのように。 これはC++で可能ですか?

は、私はあなたがこのような何かを意味推測

答えて

1

です。あなたは前方宣言が必要です。

#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; } 

ここで重要な点は、完全に定義されるまで、クラスへのポインタまたは参照のみを使用できることです。だから、私が与えた例では、Aのhello()メソッドは、と宣言されていることがあります。はBを参照していますが、その時点でBを定義していません。しかし、Bの定義の後、A :: hello()メソッドのの定義は、Bが気に入ったように自由に使用できます。

+0

ちょっとこれは本当に助けて! –

+1

"完全に定義されるまでは、クラスへのポインタまたは参照のみを使用できます"。あなたが知っている限りでは、関数との間で値渡しのクラスを渡すこともできます... – SadSido

+0

その_deciphering_の賞はどこにありますか? – bobobobo

1

ありがとう:

コンパイラはクラスA

をコンパイルするのsizeof(B)を知っている必要があるので、これはC++では不可能である
class B; //Forward declaration 

class A 
{ 
    private: 
    B b; 
}; 


class B 
{ 

}; 

あなたが何ができるか解決策として、次のとおりです。

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

はい私はそれを知っています。そのクラスの公開変数または関数にアクセスしたい場合はどうすればよいですか? –

+0

しかし、反対側(AをBの直下)はコンパイルがうまくいきます。 –

+0

@maxx:コンパイラは前方宣言を使ってクラスBと呼ばれるものがあることを知っていますが、それは可能ではありませんが、その内容は分かりません。 – Naveen

0

あなた一度前方declaヘッダーのre Bを使用すると、.cppファイル内でそれを使用して、パブリック変数とメソッドにアクセスすることができます。

+0

C++の実例を教えてください。ありがとうございます –

2

いくつかの目的のために前方宣言を使用できますが、実際に使用するときは完全な型を持つ必要があります。問題へのより簡単なアプローチがあるので、あなたが本当に達成したいことをより具体的に質問することをお勧めします(注文が重要な場合は、クラスAとクラスBの間の循環依存性を示す可能性があります。良い)。

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(); 
} 
関連する問題