2017-04-16 20 views
2

「内部」(ローカル)クラスのメソッドから「外部」クラスの属性にアクセスしようとしていますが、失敗します。これはローカルクラスメソッドから属性にアクセスしようとするとコンパイルエラーが発生する

class outer 
{ 
    public: 
     std::string name; 

     class inner 
     { 
      public: 
      void hello(); 
     }; 

     void dostuff(); 

}; 

void outer::inner::hello(){std::cout << "Hello " << name << "\n";} 

void outer::dostuff(){inner instanceInner; instanceInner.hello();} 


int main() 
{ 
    outer instanceOuter; 
    instanceOuter.name = std::string("Alice"); 
    instanceOuter.dostuff(); 

    return 0; 
} 

コンパイルエラーコンパイルに失敗し

9:21: error: invalid use of non-static data member 'outer::name' 
21:53: error: from this location 

を私は本当にnameは静的メンバになりたくないが、私は本当に私の特定の目的のためにと気にしないouterシングルトンです。だから私はstatic std::string name;で試してみました

コンパイルエラーだ:

/tmp/ccqVKxC4.o: In function `outer::inner::hello()': 
:(.text+0x4b): undefined reference to `outer::name' 
/tmp/ccqVKxC4.o: In function `main': 
:(.text.startup+0x1f): undefined reference to `outer::name' 
collect2: error: ld returned 1 exit status 

をあなたは私を助けることはできますか?

答えて

3

あなたの問題はhello()の機能にあります。 nameはの範囲外のです。あなたのinnerクラスの一部ではありません。

void outer::inner::hello(){ 
    std::cout << "Hello " << name << "\n"; 
} 

nameが見つからないことを知らせるエラーが得られます。残念ながら、あなたの内部クラスは、このように、これは、あなたの外側のクラスとそのメンバーの可視性を持っていません。

次の操作を実行できます。

#include <iostream> 
#include <string> 

class outer 
{ 
    public: 
     static std::string name; 

     class inner 
     { 
      public: 
      void hello(); 
     }; 

     void dostuff(); 

}; 


std::string outer::name = ""; // This is key. You need to instantiate outer's name somewhere. 

void outer::inner::hello(){std::cout << "Hello " << outer::name << "\n";} 

void outer::dostuff(){inner instanceInner; instanceInner.hello();} 


int main() 
{ 
    outer instanceOuter; 
    instanceOuter.name = std::string("Alice"); 
    instanceOuter.dostuff(); 

    return 0; 
} 

出力:私は別の答えに言及した何か(小さな変更で)繰り返し

Hello Alice 
+0

あなたの答えをありがとう。私はあなたの "こんにちは"と私の間に違いは見られません( 'void outer :: inner :: hello(){std :: cout <<" "Hello" << name << "\ n";} ')。私が誤解していることはありますか? –

+0

私はちょうどあなたがエラーがどこにあったのか、なぜそれが起こっていたのかを指摘していました。私の編集を確認すると、この@ Remi.bを管理するための提案が表示されます。 – 0xDEFACED

+0

関数に 'name'を渡すことができます。私はそれを渡さないようにしています。その理由は、私は比較的長いコード(〜1000行)を持っており、私はちょうど外側のクラスで思考全体をラップしています。私は外部クラスのすべての属性をすべての関数呼び出しに渡す必要はありません。すべての引数を引数として渡すと、最終的に小さな関数が繰り返し呼び出されるため、パフォーマンスが低下する可能性があることに注意してください。最終的には(外部クラスのインスタンスを介して各属性を呼び出さない限り)別の方法で行うことは不可能かもしれません。 –

2

similar recent SO questionに:

A C++ nested class does not share data with its outer class -- if there were the case, each instance of the inner class would be in a one-to-one relationship with a corresponding instance of an outer class and would thus add no extra functionality. Instead, the main purposes of nested classes are:

  1. Namespace meaning: outer::inner is more meaningful than outer_inner
  2. Depending on the C++ version standard, a nested class has extra visibility of the member objects of instances of the outer class
  3. Maybe others that I'm not aware of

ここには人気の高いリファレンスがあります/なぜC++で入れ子になったクラスを使用するときにレンスの質問:あなたのケースではWhy would one use nested classes in C++?

は、innerクラスは、データを参照することはできませんname a)は、特定のnameアクセスされるouterクラスのインスタンス、またはbのいずれかなし)nameouterに共通です。 oタイプconst outer&のプライベートメンバーである

inner (const outer& _o) : o(_o) {}

:第1の解決策はouterクラスを参照して構成することがinnerクラスを必要とします。あなたがしたい場合は、hello関数は、

void outer::inner::hello(){std::cout << "Hello " << o.name << "\n";} 

また

を書き込むことができる、あなたがどこかのコンパイル単位で

std::string outer::name = "bla"; 

を入れなければならないためname静的な、それは、そうでない場合は、静的メンバー未定義の参照です定義されていません。

いずれの場合でも、ネストされたクラスを悪用していることが心配です。あなたのコードにはどのような目的がありますか?外部とネストされたクラスの間でデータとメンバー関数を分離する必要があるのはなぜですか?あるクラスがあなたの目的をより良く果たさないと確信していますか?