无法理解赋值运算符的重载
Unable to understand overloading of assignment operator
为了更好地理解c++中对象的工作,我写了这段代码:
using namespace std;
char n[] = "\n";
class T
{
private:
int num;
public:
T ()
{
num = 0;
cout << n << (long)this % 0xFF << " created without param";
}
T (const int param)
{
num = param;
cout << n << (long)this % 0xFF << " created with param = " << param;
}
T (const T& obj)
{
num = obj.num;
cout << n << (long)this % 0xFF << " created as copy of " << (long)&obj % 0xFF;
}
const T& operator= (const T& obj)
{
if (this == &obj)
return *this;
num = obj.num;
cout << n << (long)this % 0xFF << " got assigned the data of " << (long)&obj % 0xFF;
return *this;
}
~T ()
{
cout << n << (long)this % 0xFF << " destroyed";
}
int get () const {return num;}
void set (const int param) {num = param;}
};
T PlusTen (T obj)
{
T newObj(5);
newObj.set( obj.get() +10 );
return newObj;
}
int main ()
{
T a, b(4);
a = b;
a = PlusTen(b);
cout << n;
return 0;
}
它工作正常,但是当我删除重载赋值运算符的 "return-type" 和 "parameter" 中的 const
限定符时,如下所示:
T& operator= (T& obj) // const removed
{
if (this == &obj)
return *this;
num = obj.num;
cout << n << (long)this % 0xFF << " got assigned the data of " << (long)&obj % 0xFF;
return *this;
}
然后这行main函数报错:
a = PlusTen(b);
错误信息为:
no match for 'operator=' (operand types are 'T' and 'T')
note:
candidate is: T& T::operator=(T&)
no known conversion for argument 1 from 'T' to 'T&'
如果'T'和'T'的操作数类型有问题,为什么它上面的那一行(a = b;
)完全没问题?它们也是操作数类型 'T' 和 'T' !!
我在这里找到了一个相关的问题,但没有找到有用的细节:
why must you provide the keyword const in operator overloads
那里有人说,如果我们不在 operator= 中使用 const
,我们只能将它用于 non-const
对象。但就我而言,双方都是非常量。那为什么会报错?尤其是当它上面的行在操作数类型上相同时,可以正常编译吗?
使用的编译器:MinGW
PlusTen(b);
正在创建临时对象。由于非常量引用不能绑定到临时对象,operator=
不能在这里调用。
在 a = b;
中 b
不是临时的,它是一个可修改的对象(所谓的 l-value)。非常量引用成功绑定到它,operator=
被调用。
为了获得更多乐趣,请尝试按如下方式定义您的 b
:
const T b(4);
这个函数
T PlusTen (T obj)
{
T newObj(5);
newObj.set( obj.get() +10 );
return newObj;
}
returns 类型为 T
的临时对象。此临时对象可以与常量引用绑定。
This is important! This is the reason OP is confused!
Non-const references to temporary objects are not allowed in C++ !! This is why promoting T
to const T
succeeded in a = b;
but failed in a = PlusTen(b);
, because RHS in the latter is temporary.
所以编译器报错是因为赋值运算符的参数
T& operator= (T& obj)
^^^^^^
不是常量引用。
return 类型中的限定符 const
使得在上下文中如何在程序中使用运算符无关紧要。
为了更好地理解c++中对象的工作,我写了这段代码:
using namespace std;
char n[] = "\n";
class T
{
private:
int num;
public:
T ()
{
num = 0;
cout << n << (long)this % 0xFF << " created without param";
}
T (const int param)
{
num = param;
cout << n << (long)this % 0xFF << " created with param = " << param;
}
T (const T& obj)
{
num = obj.num;
cout << n << (long)this % 0xFF << " created as copy of " << (long)&obj % 0xFF;
}
const T& operator= (const T& obj)
{
if (this == &obj)
return *this;
num = obj.num;
cout << n << (long)this % 0xFF << " got assigned the data of " << (long)&obj % 0xFF;
return *this;
}
~T ()
{
cout << n << (long)this % 0xFF << " destroyed";
}
int get () const {return num;}
void set (const int param) {num = param;}
};
T PlusTen (T obj)
{
T newObj(5);
newObj.set( obj.get() +10 );
return newObj;
}
int main ()
{
T a, b(4);
a = b;
a = PlusTen(b);
cout << n;
return 0;
}
它工作正常,但是当我删除重载赋值运算符的 "return-type" 和 "parameter" 中的 const
限定符时,如下所示:
T& operator= (T& obj) // const removed
{
if (this == &obj)
return *this;
num = obj.num;
cout << n << (long)this % 0xFF << " got assigned the data of " << (long)&obj % 0xFF;
return *this;
}
然后这行main函数报错:
a = PlusTen(b);
错误信息为:
no match for 'operator=' (operand types are 'T' and 'T')
note:
candidate is: T& T::operator=(T&)
no known conversion for argument 1 from 'T' to 'T&'
如果'T'和'T'的操作数类型有问题,为什么它上面的那一行(a = b;
)完全没问题?它们也是操作数类型 'T' 和 'T' !!
我在这里找到了一个相关的问题,但没有找到有用的细节:
why must you provide the keyword const in operator overloads
那里有人说,如果我们不在 operator= 中使用 const
,我们只能将它用于 non-const
对象。但就我而言,双方都是非常量。那为什么会报错?尤其是当它上面的行在操作数类型上相同时,可以正常编译吗?
使用的编译器:MinGW
PlusTen(b);
正在创建临时对象。由于非常量引用不能绑定到临时对象,operator=
不能在这里调用。
在 a = b;
中 b
不是临时的,它是一个可修改的对象(所谓的 l-value)。非常量引用成功绑定到它,operator=
被调用。
为了获得更多乐趣,请尝试按如下方式定义您的 b
:
const T b(4);
这个函数
T PlusTen (T obj)
{
T newObj(5);
newObj.set( obj.get() +10 );
return newObj;
}
returns 类型为 T
的临时对象。此临时对象可以与常量引用绑定。
This is important! This is the reason OP is confused!
Non-const references to temporary objects are not allowed in C++ !! This is why promotingT
toconst T
succeeded ina = b;
but failed ina = PlusTen(b);
, because RHS in the latter is temporary.
所以编译器报错是因为赋值运算符的参数
T& operator= (T& obj)
^^^^^^
不是常量引用。
return 类型中的限定符 const
使得在上下文中如何在程序中使用运算符无关紧要。