能够在类定义之外访问私有对象成员

时间:2019-04-15 19:43:48

标签: c++

似乎我的代码违反了不能在类定义之外访问对象的私有成员的规则。

我有一个像这样的类定义

class Test{
private:
    int x;
public:
    const Test& operator=(const Test &other){
        this->x = other.x;
        return *this;
    }
    void addX(int);
    void getX();
};

让我困惑的是,我能够访问Test类的对象“ other”的私有成员

这似乎不正确,或者正确,我必须缺少一些基本信息

3 个答案:

答案 0 :(得分:6)

您可以访问相同类型的任何实例的私有(和受保护)成员。这包括静态成员,以及私有或受保护的继承基。

几个例子:

class Base {
protected:
    int y;
private:
    int z;
};
class Sub;
class Test : private Base {
private:
    int x;
public:
    const Test& operator=(const Test &other) {
        this->x = other.x; // Can access private members for any instance
        this->y = other.y; // Can access a protected member of a base type
        this->z = other.z; // ERROR: Neither side is OK, can't access a private member of a base
        return *this;
    }
    void foo(Sub &sub);
};
class Sub : public Test
{
private:
    int w;
};
inline void Test::foo(Sub &sub) {
    int a = sub.x; // Still OK, as x is a member of Test
    a += sub.w; // ERROR: Can't access privates of subtypes however
}

答案 1 :(得分:4)

是的,这就是C ++标准规定的方式。但是,我同意这可能不是您所期望的。

要想弄清楚它,您可能想记住访问检查是编译时检查-它们在程序编译时发生,而不是在执行时发生。

现在,让我们考虑一下您的例子:

const A& operator=(const A& a) {
    x = a.x;
    return *this;
}

现在,在编译此函数时,编译器(通常,我们假装没有进行内联)无法知道A&this对象是否相同,因为可以调用它

A a;
a = a;

最重要的是-即使我们愿意,也无法进行访问修饰符检查以将类实例考虑在内。

答案 2 :(得分:3)

cppreference

中所述
  

该班级的私​​人成员只能由该班级的成员和朋友访问,无论该成员位于相同还是不同的实例上

     

class S { private: int n; // S::n is private public: S() : n(10) {} // this->n is accessible in S::S S(const S& other) : n(other.n) {} // other.n is accessible in S::S };