【问题标题】:Why C++ allows returning a reference to private members [closed]为什么 C++ 允许返回对私有成员的引用 [关闭]
【发布时间】:2013-11-17 08:32:16
【问题描述】:
class test {
public:
test(int value = 0): x(value) {}
int& get(){
    return x;
}
private:
int x;
};

这将允许客户端代码改变私有成员
这在 C++ 中是合法的,但为什么呢?
在任何情况下您实际上需要打破类封装?

【问题讨论】:

  • 容器经常使用它,以便对容器的索引行为自然。
  • 你没有破坏封装。没有什么能阻止你,class test 的编码人员,改变游戏和提供该参考的后端。您的代码的用户仍会获得一个热整数引用,您选择公开。如果你不想这样做,坦率地说,不要
  • "为什么" 这是一个语言规范。你最好问问 C++ 发明者。

标签: c++ language-design


【解决方案1】:

将成员设为私有,意味着您不能直接访问它。但是没有什么限制您通过公共成员间接访问它。这取决于你的设计。你甚至可以这样做:

class test {
public:
   test() : x(y) {}
   int &x;
private:
   int y;
};

在您的班级中,假设您要计算成员被读/写的次数。因此,您可以将其设为private,然后放置一个返回对变量的引用的成员函数:

class test {
public:
  test(int value = 0): x(value), count(0) {}
  int& get(){
      count++;
      return x;
  }
private:
  int x;
  int count;
};

我希望这个例子能说明如何将成员设为私有,然后对其进行间接访问。

【讨论】:

  • +1 获取创意和说明性示例!
【解决方案2】:

首先让我们考虑实施您所描述的内容。正确地这样做将是非常繁重的。你的例子很简单。但是,如果引用在到达暴露它的函数之前流经了许多函数怎么办?编译器必须进行异常复杂的静态分析,超出编译器编写者合理期望的静态分析级别。

因此,即使设计师想禁止这一点,也不会那么容易做到。设计师会想要阻止这种情况吗?很可疑。如果他们这样做了,[] 运算符将如何在容器或字符串上实现?

在任何情况下您实际上需要 打破类封装

如容器和字符串上的 [] 运算符示例所示,此功能实际上用于支持封装。

【讨论】:

  • operator[] 在标准容器上不返回对私有成员的引用。它返回对私有成员(直接或间接)指向的对象的引用。
  • 这可能是一个技术问题,但我认为在这种情况下这是一个重要的区别,因为 operator[] 所做的实际上是有用的,而且要找到一个有点困难(但并非不可能)实际上确实返回对私有成员的引用的有用示例。
【解决方案3】:

为什么?因为 C++ 主要试图让你做任何你想做的事,而不是妨碍你;它不会非常努力地保证您的安全。如果您想要一种安全的语言,请使用其他语言。如果你愿意的话,你有类似面向对象的东西,但如果你想突破它,你就有更多的力量。拥有权利的同时也被赋予了重大的责任。

您甚至不需要它来破坏封装,这毫无价值;您可以简单地将指向“test”的指针重新解释为整数并以这种方式访问​​私有字段。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多