【问题标题】:private member accessible from other instances of the same class可从同一类的其他实例访问的私有成员
【发布时间】:2012-09-03 12:53:25
【问题描述】:

我刚刚注意到一些我以前从未意识到的事情。事实证明,这个类在 C# 中是有效的:

class Foo
{
    private string contents;

    public Foo(string str) {
        contents = str;
    }

    public void set(Foo other)
    {
        contents = other.contents;
    }
}

因此同一类的不同实例可以访问彼此的私有成员。

到目前为止,我认为对象的私有成员只能由该对象访问,而不能由同一类的其他实例访问。发现这一点有点令人惊讶。

在所有常见的面向对象语言中都是这种情况吗?这对我来说并不直观。

【问题讨论】:

  • 原来有人已经问过一个非常相似的问题:stackoverflow.com/questions/346127/…。但是,这个问题的答案并没有给出这种设计选择的权威理由。仅仅是因为以不同的方式做事效率低/不可能吗?

标签: oop


【解决方案1】:

这与 C++ 和 Java 中的相同:访问控制基于每个类,而不是基于每个对象。

在 C++ 中,Java 和 C# 访问控制被实现为静态的编译时特性。这样它就不会产生任何运行时开销。这种方式只能实现每个类的控制。

【讨论】:

  • 为什么会这样?编译器不能只禁止在(隐式或显式)this 引用之外的任何东西上调用私有方法吗?这意味着不能对碰巧引用this 的其他变量调用私有方法,但我看不出有任何缺点。我认为japreiss的回答更正确。
【解决方案2】:

如何为不通过公共方法公开其所有内部状态的类创建复制构造函数?

考虑这样的事情:

class Car
{
public:
    void accelerate(double desiredVelocity);
    double velocity() const;
private:
    Engine myEngine;
};

Car 的公共接口不会暴露其Engine,但您需要它来制作副本。

【讨论】:

  • 是的;这。没有其他体面的方法来制作复制/克隆方法。如果您担心它会以某种方式在程序集之外被访问,您可以将其设置为内部保护。
  • 实现equals()也是必须的。
【解决方案3】:

对于完全相同的场景,Scala 中存在“特定于对象的私有”与 Java 中也不支持的“特定于类的私有”。

class Foo {

  private[this] def contents // [this] marks the property as private to the owner

  def doFoo(other: Foo) {
    if (other.contents) { // this line won't compile
      // ...
    }
  }

}

这是一个 令人惊讶的是,其他现代语言不支持此类功能private[this] vs private,我知道这可能不是安全风险,因为它仍然与类相关联,您仍然可以通过反射访问所有私有变量,例如@987654322 @。

如果你从 Python 语言的角度来看,它们甚至没有 C# 那样广泛的范围特性,最终都是关于代码组织的,从语言设计的角度来看,这是新手必须学习的曲线通过

【讨论】:

  • 非常感谢您的解释!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-25
相关资源
最近更新 更多