C++赋值运算符重载函数的参数对象的访问成员变量的问题
如题,在C++学习的群里看到有小伙子问起赋值运算符重载函数中的参数一个实例化的对象为什么可以直接访问该实例化对象的私有成员变量(我之前也没注意…)。
Stack& operator=(const Stack& v) // 重载赋值运算符函数,实现深拷贝。
{
delete[] items;
stacksize = v.stacksize; // 就是这个。
items = new DataType[stacksize];
for (int ii = 0; ii < stacksize; ii++) items[ii] = v.items[ii];
top = v.top;
return *this;
}
结论
丢进某大模型询问得之:
如果 v 是同一类的对象,则在重载的赋值运算符函数内部,可以访问 v 对象的私有成员变量。因为在成员函数内部,无论是当前对象还是其他对象,都被视为同一类的对象。
对于 stacksize = v.stacksize; 这行代码,v.stacksize 是合法的,因为在重载的赋值运算符函数内部,我们可以访问同一类的其他对象的私有成员。虽然 v 是传递进来的对象,但是在成员函数内部,它被视为同一类的对象(在 C++ 中,私有成员的访问权限仅限于同一类的成员函数,而不受传递方式的限制)。在重载的赋值运算符函数中,可以直接访问 v 对象的 stacksize 成员变量。
那是否可以修改呢?还是仅限访问?
大模型答:
在C++中,虽然在重载的赋值运算符函数中,我们可以访问同一类的其他对象的私有成员,但这只是访问,而不是直接修改。直接修改 v 对象的私有成员 stacksize 是不允许的,会导致编译错误。
修改了代码测试, 如下:
Stack& operator=(const Stack& v) // 重载赋值运算符函数,实现深拷贝。
{
cout << "copy..." << endl;
delete[] items; // 释放原内存。
v.stacksize = 66; //尝试修改
stacksize = v.stacksize; // 栈实际的大小。
items = new DataType[stacksize]; // 重新分配数组。
for (int ii = 0; ii < stacksize; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
top = v.top; // 栈顶指针。
return *this;
}
确实报错。
再添加一行代码直接访问v的私有成员变量
Stack& operator=(const Stack& v) // 重载赋值运算符函数,实现深拷贝。
{
cout << "copy..." << endl;
delete[] items; // 释放原内存。
cout << v.stacksize << endl;
stacksize = v.stacksize; // 栈实际的大小。
items = new DataType[stacksize]; // 重新分配数组。
for (int ii = 0; ii < stacksize; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
top = v.top; // 栈顶指针。
return *this;
}
确实可以通过。
对于 cout << v.stacksize << endl; 这行代码,如果 v 是同一类的对象,它在重载的赋值运算符函数内部是合法的。在成员函数内部,可以自由地访问同一类的其他对象的私有成员变量。因此,如果 v 是 Stack 类的对象,并且这段代码位于 Stack 类的成员函数内部,那么它是合法的。
附上该类的代码,方便直接测试
#include<iostream>
#include<climits> // 使用INT_MAX所需要引入的头文件
using namespace std;
template <class DataType>
class Stack // 栈类
{
private:
DataType* items; // 栈数组。
int stacksize; // 栈实际的大小。
int top; // 栈顶指针。
public:
// 构造函数:1)分配栈数组内存;2)把栈顶指针初始化为0。
Stack(int size = 3) :stacksize(size), top(0) {
items = new DataType[stacksize];
}
~Stack() {
delete[] items; items = nullptr;
}
Stack& operator=(const Stack& v) // 重载赋值运算符函数,实现深拷贝。
{
cout << "copy..." << endl;
delete[] items; // 释放原内存。
cout << v.stacksize << endl;
stacksize = v.stacksize; // 栈实际的大小。
items = new DataType[stacksize]; // 重新分配数组。
for (int ii = 0; ii < stacksize; ii++) items[ii] = v.items[ii]; // 复制数组中的元素。
top = v.top; // 栈顶指针。
return *this;
}
bool isempty() const { // 判断栈是否为空。
return top == 0;
}
bool isfull() const { // 判断栈是否已满。
return top == stacksize;
}
bool push(const DataType& item) { // 元素入栈。
if (top < stacksize) { items[top++] = item; return true; }
return false;
}
bool pop(DataType& item) { // 元素出栈。
if (top > 0) { item = items[--top]; cout << item<<endl; return true; }
return false;
}
};
int main() {
// 创建两个栈对象
Stack<int> stack1(5);
stack1.push(10);
stack1.push(20);
stack1.push(30);
Stack<int> stack2;
// 使用赋值操作符将 stack1 的内容复制到 stack2 中
stack2 = stack1;
return 0;
}