如何避免私有成员通过类对象访问外部单词
How to avoid private members access by class object outside word?
我在某个地方发现,我们可以通过类的对象修改它的私有成员。我想避免这种情况,因为它违反了封装的C++规则。
#include <iostream>
using namespace std;
class TClass
{
private:
int i;
public:
int GetVal() { return i; }
};
int main()
{
TClass obj;
int* ptr = (int*)&obj;
*(ptr+0) = 10;
cout<<"Object Value = "<<obj.GetVal()<<endl;
return 0;
}
我试图通过将(&)运算符的地址重载为来解决这个问题
class TClass
{
private:
TClass* operator&() { return this; }
int i;
public:
int GetVal() { return i; }
};
请分享您对此的宝贵想法。
我不同意指针是"危险武器"的观点。它们只是语言的一部分,也是语言不可或缺的一部分。指针本身并没有什么危险——唯一危险的是程序员的无知,他们在不知道如何安全地使用指针的情况下使用指针。
关于您关于operator&
过载的问题,我的建议是:不要。
让我们在这里把问题扩大一点。你并不是在问operator&
过载的问题。您真正想知道的是,采取英勇步骤来阻止人们访问您类中的private
数据成员是否合适?
我说,不,不是。只需制作private
的私有部件,就可以了。有几个原因。
首先,也许也是最重要的一点,这样做会增加代码的复杂性。你写的每一行代码都是另一个潜在的错误来源。代码的"太空时代"或技术性越强,产生的错误就越难识别和修复。它还使您的代码更加脆弱,使您将来编写的代码更有可能破坏您今天编写的代码。
接下来,采取这些步骤是徒劳的。我几乎可以向你保证,无论你采取什么措施来阻止我修改你类的private
数据成员,我都能找到一种方法来击败这些措施。private
就像一把门锁。它的设计并不是为了让门后的东西绝对安全。它确实是为了让诚实的人保持诚实,并劝阻那些不那么坚定的不诚实的人。一个意志坚定、技术娴熟的程序员会打败你能设计的任何锁。
另一个原因是,尽管这看起来极不可能,也极为可疑,但程序员可能会出于正当理由试图访问private
成员。你不可能知道几年后代码的所有使用方式。如果程序员能够找到一种既合法又安全的访问private
的方法(例如,不调用未定义的行为),则不应妨碍他们。显然,与其这样做,不如简单地修改类。
人们忽略的private
的主要一点是,它不是为了安全目的,而是为了分离接口和实现细节,所以不惜任何代价强制执行它是没有意义的。
换句话说,它是类的用户的安全网;正因为如此,它的设计并不是万无一失的——它可以帮助你避免错误,但如果你决心绕过它,C++不会阻止你。
至于您的解决方案,可以很容易地绕过它,只需在使用&
之前强制转换为char &
即可。
TClass obj;
int* ptr = (int*)&((char &)obj);
(这是std::addressof
通常使用的技巧,标准保证它能工作)
- 按基类对象访问派生类资源时出错
- 使用基类对象访问派生的仅类方法
- 从 const 对象访问非 const 方法
- 如何在C++中使用类对象访问指针数据成员
- 如何通过不同的指针使用类的对象访问结构?(链表)(C++)
- 使用二进制搜索树中的迭代器对象访问左侧节点
- 为什么引用类型在使用临时对象访问时是左值
- 从父对象 c++ 访问子方法
- 无法通过指针或对象 c++ 访问受保护的成员
- 为什么可以从类中的对象访问类的私有变量
- 对类似"struct {double, int}"对象使用reinterpret_cast进行对象访问
- 通过无符号 char 别名进行对象访问,加载和存储时会发生什么?
- 从对象访问结构枚举
- 如何全局创建对象并使用该对象访问全局范围内的公共成员函数
- 在C 中,可以从第三个共享对象访问其他两个不同共享对象
- 如何在C 中提供一个可呼叫的对象访问,例如lambda
- C 向量对象访问
- C++是否可以从同级第二个派生对象访问第一个派生对象的受保护基础数据成员?
- 如何从类内实例化的对象访问私有变量
- 多态性:通过类文本或对象访问静态成员