如何避免私有成员通过word对象访问word?

时间:2013-12-13 15:18:10

标签: c++

我找到了一个可以通过其对象修改类的私有成员的地方。我想避免这种情况,因为它违反了Encapsulation的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; 
}

我试图通过将addressof(&amp;)运算符重载为

来解决这个问题
class TClass
{
  private:
    TClass* operator&() { return this; }
    int i;

  public:
    int GetVal() { return i; }
};

请分享您对此的宝贵想法。

2 个答案:

答案 0 :(得分:7)

我不同意指针是“危险武器”的想法。它们只是语言的一部分,是其中不可或缺的一部分。指针本身并没有什么危险 - 唯一危险的是程序员的无知,他们在不知道如何安全地使用它们的情况下使用它们。

关于超载operator&的问题,我的建议是:不要

让我们在这里稍微扩大一下这个问题。你并不是真的要求重载operator&。您真正想知道的是,采用英雄步骤来阻止人们访问您班级中的private数据成员是否合适?

我说,不,不是。只需创建私有部分private,然后保留即可。有几个原因。

首先,也许最重要的是,这样做会增加代码复杂性。您编写的每一行代码都是另一个潜在的错误来源。代码越“空间时代”或技术越多,识别和修复所产生的错误就越困难。它还会使您的代码更加脆弱,使您将来编写的代码更有可能破坏您今天所写的内容。

接下来,采取这些步骤是徒劳的。我几乎可以向你保证,无论你采取什么步骤来阻止我修改你班级的private数据成员,我都能找到一种方法来击败这些措施。 private就像锁在门上。它的设计并不是为了让那扇门背后绝对安全。确实让诚实的人诚实,并劝阻那些不那么坚定的不诚实的人。一个坚定,熟练的程序员将击败你可以设计的任何锁。

另一个原因是,虽然看起来非常不可能并且非常可疑,但程序员可能会出于正当理由尝试访问private成员。您无法知道几年后您的代码可能会被使用的所有方式。如果程序员能够找到以合法和安全的方式访问private的方法(例如,不调用未定义的行为),则不应该阻挡他们。显然,最好只修改你的课而不是这样做。

答案 1 :(得分:1)

人们错过private的主要观点是它不是出于安全目的,而是来分离界面和实现细节,因此不惜任何代价强制执行它。

换句话说,它是该类用户的安全网;因此,它不是为万无一失而设计的 - 它可以帮助你避免错误,但如果你决心绕过它,C ++不会阻止你。

至于您的解决方案,可以轻松规避它,只需在使用char &之前转换为&

TClass obj;
int* ptr = (int*)&((char &)obj);

(这是std::addressof通常使用的技巧,标准为guaranteed to work