这里我们有一个class Bucket 有两个私有数据成员。还有构造函数、复制构造函数和其他一些函数。让我们把注意力转向modifyOther 函数。它接受一个参数,即指向Bucket 对象的指针。然后该成员函数可以编辑其他 Bucket 对象。
#include <iostream>
using namespace std;
class Bucket {
public:
// Acts as constructor acceptint two arguments x and y,
// one argument x,
// or no arguments (default constructor).
Bucket(int x = 0, int y = 0) : x(x), y(y) {}
Bucket(const Bucket& rhs)
{
this->x = rhs.x;
this->y = rhs.y;
}
void modifyOther(Bucket* other)
{
other->x = -1;
other->y = 1;
}
void printInfo()
{
cout << "x = " << this->x << endl;
cout << "y = " << this->y << endl;
cout << endl;
}
private:
int x;
int y;
};
int main()
{
Bucket a(10, 5);
a.printInfo();
Bucket b(8, 9);
b.printInfo();
a.modifyOther(&b);
a.printInfo();
b.printInfo();
return 0;
}
在main() 函数中,我们声明了两个class Base 类型的对象。请注意,它们是相同的数据类型。这很重要。然后我们调用对象a的modifyOther函数成功修改对象b的内部私有数据成员。
这是这段代码的输出:
x = 10
y = 5
x = 8
y = 9
x = 10
y = 5
x = -1
y = 1
现在您可能会想,这不应该是非法的吗?私有数据成员不是只允许对象本身访问吗?事实证明,private 和 public 这样的成员访问说明符是由编译器强制执行的,编译器没有单个对象的概念,只有类。
private 数据成员被允许被其类内的任何东西访问,被允许被类的成员函数访问。由于modifyOther 是class Base 类型的成员函数,它可以访问private 变量int x 和int y 并更改它们。因此,这里没有违反任何规则。
什么是成员函数?它只是一个独立的函数,它接受一个指向调用对象的“不可见”指针,并通过该指针访问该对象。该指针称为this。查看printInfo 函数。我使用this->y 表示成员变量是有原因的。因为所有成员函数都采用一个“不可见的”this 指向调用对象的指针,所以函数实际上看起来像:
void printInfo(Bucket* this)
{
cout << "x = " << this->x << endl;
cout << "y = " << this->y << endl;
cout << endl;
// this->x = -1;
}
请注意,我故意在此函数中添加了最后一行。将printInfo 函数的定义与modifyOther 函数的定义进行比较。它们看起来非常相似。事实上,唯一的区别是Bucket* 参数的名称! Bucket* this 是指向调用对象的隐式指针。 Bucket* other 只是一个指向其他 Bucket 对象的指针。编译器是“愚蠢的”,它无法仅根据它们的名称来区分这两个Bucket *s。它对他们一视同仁!因此我们可以得出结论,用于修改调用对象的相同机制也可以用于修改相同类类型的另一个对象。
请记住,我们不能使用相同的技巧将指针传递给 另一个 类类型的对象并对其进行修改。这是行不通的。成员函数只能访问在同一类中的变量! private 表示该变量只能由该特定类的成员函数修改,不能由任何其他类修改。一个priavte变量不能被外界修改,所以外界也包含了不同类的任何成员函数。
如果你不理解这个话题,请看我在 StackOverflow 上的类似问题,也请观看我在研究这个话题时发现的这个 YouTube 视频。
Are there multiple member functions compiled for each C++ object?
What is the 'this' pointer?
https://www.youtube.com/watch?v=_Wv-lEl1sgg&t=0s