2017-04-16 46 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

感謝您的回答。我看不出你的「hello」和我的區別(void outer :: inner :: hello(){std :: cout <<「Hello」<< name <<「\ n」;}')。我有什麼誤解嗎? –

+0

我只是指出你的錯誤謊言和爲什麼發生。如果你現在檢查我的編輯,你可以看到一個建議來管理這@ @ Remi.b – 0xDEFACED

+0

我可以傳遞'name'給函數。我試圖不通過它。原因是我有一個相對較長的代碼(約1000行),我只是將整個想法包裹在一個外部類中。我希望不必將外部類的每個屬性都傳遞給每個函數調用。請注意,將所有參數作爲參數傳遞最終可能會降低性能,對於那些可能有5個參數作爲參考傳遞的小函數,這些小函數也會被重複調用。否則最終可能無法做到(除非通過外部類的實例調用每個屬性) –

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使用嵌套類++ erence問題:Why would one use nested classes in C++?

在你的情況下,inner類不能引用數據name沒有任何一)outer類,其name的具體實例將訪問,或b )通用於outer的靜態name。第一種解決方案需要inner類與一種outer類的引用來構造:

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

其中oconst outer&類型的私有成員。然後hello功能寫入

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

另外,如果你想name一成不變的,它是一個未定義的引用,因爲你必須把

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

編譯單元中的某處,否則靜態成員沒有定義。

不管怎樣,我都擔心你濫用嵌套類。它在你的代碼中有什麼用途?爲什麼數據和成員函數必須在外部類和嵌套類之間分開?你確定一個班級不會更好地爲你的目的服務嗎?

相關問題