混淆私有变量访问

Confusing Private variable access

本文关键字:变量 访问      更新时间:2023-10-16

一个实例的私有变量能否在其他实例的函数中可用

下面的代码打印5
#include <iostream>
class A
{
    public:
        A(int value) {
            x = value;
        }
        void printValue(A *obj) {
            std::cout << obj->x;
        }
    private:
        int x;
};
void main()
{
    A obj1(3);
    A obj2(5);
    obj1.printValue(&obj2);
    getchar();
    return;
}
谁能解释一下为什么会这样?谢谢你。

可以。private:protected:限制是针对类的,而不是针对实例的。重要的是执行访问的代码位于何处。如果访问某些private的代码位于同一类中,或者位于friend classfriend函数中,则允许访问

private的范围适用于该类型中的任何内容,而不仅仅是this实例。

From MSDN:"当在类成员列表前面时,private关键字指定这些成员只能从类的成员函数和友元访问。"

让我们修改printValue:

void printValue() 
{
    A *obj = this;
    std::cout << obj->x;
}

如果你说这个不应该被编译,因为obj试图访问其他对象的元素。如果这种情况成立,任何类都不能访问它自己的元素。复制/移动构造函数,(移动)赋值操作符不能工作

是Obj1和Obj2都属于a类,所以成员函数当然可以访问对象内部的任何内容。为了获得更多的理解,您应该尝试理解成员函数实际上是如何在调用它的对象上操作的。

让我们以你的例子为例,再增加一个函数printValue()来解释更多:

#include <iostream>
class A
{
    public:
        A(int value) {
            x = value;
        }
        void printValue(A *obj) {
            std::cout << obj->x;
        }
        void printValue() {             // who supplies 'this' pointer accessible inside the function
            std::cout<< this->x;
        }
    private:
        int x;
};
void main()
{
    A obj1(3);
    A obj2(5);
    obj1.printValue(&obj2);
    getchar();
    return;
}

注意,我增加了一个成员函数void printValue();它使用这个->x,这是由编译器和

的函数调用提供的。

obj1.printValue(&obj2)被编译器翻译成printvalue(this, &obj2)。这就是为什么当你调用我添加的obj1.printValue()时,它会被调用printValue(this),其中this = &obj1由编译器提供。

因此成员函数总是使用对象的指针访问对象。在你的例子中,有两个对象:一个是你提供的,另一个是编译器提供的。

我希望这能解释你的疑问。

这种行为不仅合乎逻辑,而且非常有用。考虑

class Point2D {
  public:
    Point2D (int x, int y) : x(x), y(y);
    Point2D& operator+=(const Point2D& other) {
      x += other.x;
      y += other.y;
      return *this;
    }
  private:
    int x, y;
}

如果你不能访问operator+=中的other的私有成员,你将被迫使用公共getter和setter,并且xy私有的全部意义将会失去。因此,private对外部世界隐藏了成员,但不会对同一类的实例隐藏成员。