有选择地隐藏 class 的成员中的成员
Selectively hide member of member of class
// 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.h
中包含了 People.h
,在 People.h
中包含了 PhysicalTraits.h
。所以,编译PhysicalTraits.h
时,在定义PhysicalTraits
对象之前,会跳转到People
对象的定义,这就需要定义PhysicalTraits
对象。
如何避免这个 "mutual-include" 问题,同时仍然确保 Me
类型的对象无法访问 traits.age
?
您不必在 PhysicalTraits.h
中包含 People.h
。那里不需要 class People
的完整定义。您可以声明 class.
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++ 中,你的代码(通常)是从上到下解析的,当你需要使用例如调用后定义的函数。这就是声明被执行的原因。
在您的情况下,编译器只需要知道 class 的名称,因此声明就足够了。但是,您不能创建仅声明或调用其任何方法的 class 的对象。
还值得注意的是,在任何可能的地方都使用声明可以加快编译速度,因为解析定义显然需要一些时间。
// 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.h
中包含了 People.h
,在 People.h
中包含了 PhysicalTraits.h
。所以,编译PhysicalTraits.h
时,在定义PhysicalTraits
对象之前,会跳转到People
对象的定义,这就需要定义PhysicalTraits
对象。
如何避免这个 "mutual-include" 问题,同时仍然确保 Me
类型的对象无法访问 traits.age
?
您不必在 PhysicalTraits.h
中包含 People.h
。那里不需要 class People
的完整定义。您可以声明 class.
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++ 中,你的代码(通常)是从上到下解析的,当你需要使用例如调用后定义的函数。这就是声明被执行的原因。 在您的情况下,编译器只需要知道 class 的名称,因此声明就足够了。但是,您不能创建仅声明或调用其任何方法的 class 的对象。
还值得注意的是,在任何可能的地方都使用声明可以加快编译速度,因为解析定义显然需要一些时间。