2017-06-21 50 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值得注意的是,在可能的地方使用声明可以加快编译速度,因为解析定义显然需要一些时间。 –