通过声明成员私有,非好友函数无法直接访问该成员。但是有一种方法可以通过使用指针的类型转换来访问它们,例如:
class Foo {
private:
int value;
public:
inline int get() {
return value;
}
inline Foo (int value) {
Foo::value = value;
}
} foo(1234);
int main() {
using namespace std;
cout << foo.display() << endl; // display 1234
int *p = (int *)(&foo); // HERE!
*p = 5678;
cout << foo.display() << endl; // display 5678, foo.value has been changed
return 0;
}
我们可以阻止用户使用这些技巧吗?或者我们可以禁止将Foo *
转换为int *
吗?
答案 0 :(得分:4)
嗯,不,不可能阻止确定的程序员进行显式类型转换,因为确定的程序员可以使用几乎无限的方式 - 特别是如果愿意接受潜在的未定义行为。
哲学上,C ++类型系统通常旨在使事故更难以做事。但是,它并不是为了防止程序员故意破坏类型系统。
通过使用技术组合可能会使事情变得更加困难;
operator&()
,这会阻止使用&object
获取对象的地址。this
的成员函数,也不返回任何私有或受保护类数据的地址(或引用)。并且没有公开数据。答案 1 :(得分:2)
一种选择是使用PIMPL惯用法,并且永远不要将实现类标题包含在库中。
class A
{
Aimpl* a_;
public:
int getValue();
};
现在用户可以访问但永远不会知道Aimpl的内部修改它。
答案 2 :(得分:0)
您无法阻止任何人在您展示时编写看似有效且正常工作的代码。
貌似因为
*p = 5678;
实际上是未定义的行为,不能依赖于给出与您相同的结果。