2015-05-29 84 views
1

爲什麼不編譯下面的代碼,我該如何解決它?我得到的錯誤是:如何用C++中的朋友聲明來解決循環依賴問題?

使用未聲明的標識符的「富」

雖然Foo被明確宣佈,並在發生錯誤(在friend聲明中Bar)點確定。

foo.h中

#ifndef FOO_H 
#define FOO_H 

#include "bar.h" // needed for friend declaration in FooChild 

class Foo { 
public: 
    void Func(const Bar&) const; 
}; 

class FooChild : public Foo { 
    friend void Bar::Func(FooChild*); 
}; 

#endif 

Foo.cpp中

#include "foo.h" 

void Foo::Func(const Bar& B) const { 
    // do stuff with B.X 
} 

bar.h

#ifndef BAR_H 
#define BAR_H 

#include "foo.h" 

class Bar { 
public: 
    void Func(FooChild*) {} 
private: 
    int X; 
    friend void Foo::Func(const Bar&) const; // "use of undeclared identifier 'Foo'" 
}; 

#endif 

Here是上述代碼的一個可編譯的在線版本。

+0

這將是少了很多混亂,如果你並不需要'這樣friend'事情。保持你的私人私密。 – tadman

+0

@tadman我使用'friend'而不是爲'X'創建getter的原因就是這樣,只有需要'X'的代碼才能訪問它,而不是讓所有訪問'Bar'的代碼都可以訪問到'X'。 – emlai

+0

看到這樣的事情通常是一個破碎的面向對象設計的標誌。如果有一件事*需要*訪問'X',則創建一個訪問器。用「私人」和「朋友」來鎖定事物通常是有點矯枉過正的,因爲一開始就沒有調用訪問器就足夠了。希望你相信自己。 – tadman

回答

3

FooChild放在它自己的頭文件中。

了foo.h:

#ifndef FOO_H 
#define FOO_H 

class Bar; 

class Foo { 
public: 
    void Func(const Bar&) const; 
}; 

#endif 

foochild.h:

#ifndef FOOCHILD_H 
#define FOOCHILD_H 

#include "foo.h" 
#include "bar.h" 

class FooChild : public Foo { 
    friend void Bar::Func(FooChild*); 
}; 

#endif 
+0

我記得它的行爲與我的(現在已刪除的)答案中提到的不同,它不允許將特定的類成員函數聲明爲「friend」,而只是聲明整個類或使用獨立函數。這是用現行標準(C++ - 11)修正的嗎? –

+0

@πάνταῥεῖ是的,可以在C++ 11中聲明成員函數爲朋友,儘管我不知道在早期標準中是否有可能。 – emlai

+0

@πάνταῥεῖ,第11.3/5節給出了作爲朋友聲明的成員函數的例子。 –