防止程序员使用任何技巧来访问私有类成员
Prevent programmer from using any trick to access private class member
通过声明成员private,非友元函数不能直接访问该成员。但是有一种方法可以通过使用指针的类型强制转换来访问它们,例如:
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 *
吗?
嗯,不,不可能阻止一个有决心的程序员进行显式类型转换,因为一个足够有决心的程序员可以使用的方法几乎是无限的——特别是如果愿意接受潜在的未定义行为的话。
从哲学上讲,c++类型系统通常被设计成使意外事件更难发生。然而,它不是为了防止程序员故意破坏类型系统而设计的。
通过使用多种技术组合可以使事情变得更加困难;
- 使用粉刺习语(parapura rajkumar在回答中已经提到)
- 向成员(包括pimpl)引入偏移量。例如,对于程序员来说,实现细节可能会偏移18个字节,这并不一定很明显。
- 为你的类提供一个私有的
operator&()
,这将防止使用&object
来获取对象的地址。 - 不要提供返回
this
的成员函数,不要返回任何私有或受保护类数据的地址(或引用)。而且没有公开的数据。
一种选择是使用PIMPL习惯用法,并且不将实现类头文件作为库的一部分。
class A
{
Aimpl* a_;
public:
int getValue();
};
现在用户可以访问但是不知道如何修改Aimpl的内部结构
您无法阻止任何人编写您所展示的看似有效且可工作的代码。
似乎是因为
*p = 5678;
实际上是未定义的行为,不能指望给出与您相同的结果。
相关文章:
- C++ 传递指向对象的指针的指针,无法访问成员
- 从不同C++类的成员变量访问成员函数
- 使用 getter 访问成员变量C++
- 如何使用包含内部类的类实例有效地从内部类访问成员?
- 通过多个类访问成员时出错
- 如何在使用对象指针时访问成员函数
- 为什么相应成员不能正确访问成员函数指针
- 从两个不同类继承的非虚拟基类的访问成员
- 如何使用 gcc 内联汇编器代码访问成员变量
- 如何使用常数向量访问成员函数
- 访问成员函数中参数的类成员
- C++嵌套结构初始化和访问成员
- 通过指向班级第一个成员的指针访问成员是不确定的行为吗?
- 如何使用C STD :: SET中的迭代器访问成员功能
- 访问成员C 时,结构的向量生成了范围的错误
- 带指针的班级访问成员
- 从聚合类访问成员变量
- 如何访问成员变量 sqlite 回调
- ctypes/C++segfault访问成员变量
- 通过父类型的指针或直接从派生类访问成员函数的差异