为什么隐私是基于每个 class 的,但 const 不适用于相同 class 的对象?

Why is privacy on a per-class basis but const doesn't work across objects of the same class?

出于好奇,我决定尝试一些东西,看看它是如何工作的。我想看看 class 的一个对象是否可以访问同一 class 的另一个对象的私有变量。显然它可以,如果这个程序是任何指标:

#include <iostream>

using namespace std;

class Colour
{
private:
    int var;
public:
    void setVar(int x)
    {
        var = x;
    }
    int getVar() const
    {
        return var;
    }
    int getOtherVar(Colour col) //steals the private var of another Colour object
    {
        return col.var;
    }
};

int main()
{
    Colour green;
    Colour red;

    green.setVar(54);
    red.setVar(32);

    cout << "Green is " << green.getVar() << endl;
    cout << "Red is " << red.getVar() << endl;
    cout << "Green thinks Red is " << green.getOtherVar(red) << endl;


    return 0;
}

我有点期待它会以 class 的每个唯一实例只能访问 它自己的 私人成员的方式失败。我做了一些研究,发现隐私 is a class-specific thing, not an instance-specific thing.

无论如何,我决定进一步试验并发现了一些令人困惑的东西。我编辑了 getOtherVar() 的实现并将其变成了这个:

    int getOtherVar(Colour col) const
    {
        col.var = 67;
        return col.var;
    }

我想如果对象可以访问彼此的成员,那么 const 关键字不应该保护相同 class 的其他对象不被更改吗?它没有,我不知道为什么。

getOtherVar 的当前声明只是确保调用该方法的实例仍然是 const。如果您希望强制执行 col 不能被修改,您需要

int getOtherVar(const Colour& col) const
{
    col.var = 67;    // <== this will not be allowed
    return col.var;
}

const 成员函数使 const 仅成为您为其调用该函数的对象,即 *this。也就是说,该成员函数的“隐藏”参数 this 是指向常量的指针。但这并不能避免修改col参数。

要创建另一个对象 const,只需将其传递给 const 参数即可。在您的情况下,您可能希望通过 const 引用传递它:

int getOtherVar(const Colour& col) const
{
  col.var = 67;  // will not compile
  return col.var;
}

按值传递将使用函数参数的副本。


至于 per-class 访问,如果它是 per-instance 而不是,您将如何实现 copy/move 构造函数和赋值运算符?或其他函数,例如二元运算符等...

考虑一下这个论点:当您设计 class 时,您可以完全控制它的实现。这意味着保护此 class 的其他对象的成员免受您自己的侵害没有多大意义......对于其他 classes,甚至是派生的对象,情况恰恰相反:这是某人否则可能会发展。这就是保护您 class 的成员免受其他 class 成员侵害的原因。

至于const方法,区别在于隐藏参数this。非常量方法具有 Class* 类型的参数,而常量方法具有 const Class* 类型的参数。此规则不会影响可能可变的其他参数,即使它们属于相同的 class.