如何避免私有成员通过类对象访问外部单词

How to avoid private members access by class object outside word?

本文关键字:对象 访问 外部 单词 何避免 成员      更新时间:2023-10-16

我在某个地方发现,我们可以通过类的对象修改它的私有成员。我想避免这种情况,因为它违反了封装的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通常使用的技巧,标准保证它能工作)