2017-06-21 96 views
0
// PhysicalTraits.h 
struct PhysicalTraits { 
    unsigned int age; // years 
    double height; // meters 

    PhysicalTraits(const double H = 0.0, const unsigned int A = 0u) : age (A), height(H) {}; 
    ~PhysicalTraits() {}; 
}; 

// People.h 
#include <PhysicalTraits.h> 
class People { 
    PhysicalTraits traits; 

public: 
    People(const double H = 0.0, const double A = 0u) : traits(H, A); 
    ~People() {}; 

    void displayAge() { std::cout << "You are " << traits.age << " years old." << std::endl; } 
    void displayHeight() { std::cout << "You are " << traits.height << " meters tall." << std::endl; } 
}; 

// Me.h 
#include <PhysicalTraits.h> 
class Me { 
    PhysicalTraits traits; 

public: 
    Me(const double H = 0.0) : traits(H); 
    ~Me() {}; 

    void displayAge() { 
     // I want `traits.age` to throw an error 
     std::cout << "You are " << traits.age << " years old." << 
    } 
    void displayHeight() { 
     std::cout << "You are " << traits.height << " meters tall." << std::endl; 
    } 
}; 

我打算允許People類型的對象訪問traits.age。但是,我不想知道我的年齡,所以我想限制Me類型的對象訪問traits.age有選擇地隱藏類的成員

要做到這一點,我修改PhysicalTraits.h

#include <People.h> 
struct PhysicalTraits { 
    double height; // meters 
private: 
    unsigned int age; // years 
    friend class People; // Objects of type `People` can access age 
}; 

隨着age作爲一個私有成員變量,並與People朋友,但不是Me。我已經解決了這個問題......有點。

然而,的問題是,我已經包括在PhysicalTraits.hPeople.hPhysicalTraits.hPeople.h。因此,在編譯PhysicalTraits.h時,在定義PhysicalTraits對象之前,它將跳轉到People對象的定義,該對象要求定義PhysicalTraits對象。

如何避免此「互相包含」問題,同時仍確保Me類型的對象無法訪問traits.age

回答

1

您不必在PhysicalTraits.h中包含People.h。那裏不需要完整定義類People。你可以聲明這個類。

PhysicalTraits.h看起來就像是:

class People; // Forward declaration 

struct PhysicalTraits { 
    double height; // meters 
private: 
    unsigned int age; // years 
    friend class People; // Objects of type `People` can access age 
}; 

前向聲明是爲了解決像你這樣的問題正是建立(互有)。在C++中,你的代碼是(通常)從上到下進行解析的,這在你需要使用時會產生很多問題。在調用之後定義的函數。這就是爲什麼宣言得以實施。 在你的情況下,編譯器只需要知道類的名字,所以聲明就足夠了。但是,您不能創建只聲明或調用其任何方法的類的對象。

值得注意的是,在可能的地方使用聲明可以加快編譯速度,因爲解析定義顯然需要一些時間。

+0

感謝您的簡單答案。你有什麼機會知道爲什麼C++(XX/11)允許你提前宣佈這樣的類?無論出於何種原因,在我看來,它似乎質疑數據必須強類型的概念......(**注意:**對於我的「無符號雙倍」錯字表示歉意) –

+1

@VladislavMartin這完全是爲了解決像你這樣的問題互有)。在C++中,你的代碼是(通常)從上到下進行解析的,這在你需要使用時會產生很多問題。在調用之後定義的函數。這就是爲什麼宣言得以實施。在你的情況下,編譯器只需要知道類的名稱,所以聲明就足夠了。但是,您不能創建只聲明或調用其任何方法的類的對象。 –

+0

@VladislavMartin值得注意的是,在可能的地方使用聲明可以加快編譯速度,因爲解析定義顯然需要一些時間。 –