举个必须要用重载运算符和重载运算符时必须要使用引用的例子
class Myclass {
private:
char* str;
public:
Myclass( char* str1 = "default string" )
{
str = new char[strlen( str1 ) + 1];
strcpy( str, str1 );
cout << "constructor called" << endl;
}
~Myclass()
{
cout << "destrustor called" << endl;
}
void showChar()
{
cout << str << endl;
}
Myclass &operator = (const Myclass &ele) {
delete[] str;
str = new char[strlen( ele.str ) + 1];
strcpy( str, ele.str );
return(*this);
}
};
int main()
{
Myclass class1( "string1" );
Myclass class2;
class2 = class1;
class1.showChar();
class2.showChar();
return(0);
}
这里我们重载了赋值运算符,将class1的str赋给了class2.str;
若我们不重载赋值运算符,用原来自带的‘=’,则会调用复制构造函数,将class1的str的值复制给class2的str,这是两个str指向统一内存。在程序完成时,调用析构函数,先调用class2的析构函数,把str所指向的内存给清除,完成后再调用class1的析构函数,由于在class2时已经把str所指向的内存给清除了,这时会出现内存泄漏。
为什么这里的重载赋值运算符一定要用引用?
若参数不用引用,则有Myclass &operator=(const Myclass ele) {
这时实参传值给形参会创建一个临时变量,调用复制构造函数将实参复制给形参,实参的str与形参的str指向同一块内存。所以,当赋值函数完成时,会清除函数的所占的内存,形参就会被清除,形参的str指向的内存也就会被清除。再调用class1.showchar()会发现内存泄漏。
输出结果如下:
constructor called
constructor called
䁷䁷䁷䁷䁷
string1
destrustor called
destrustor called
若重载运算符函数的返回类型不用引用,则有则有Myclass operator=(const Myclass &ele) {
这是返回对象时会创建一个临时对象,再调用复制构造函数,将返回的对象复制给临时对象,函数结束后,返回的对象被清除,返回对象的str所指向的内存也被清除,由于返回对象和临时对象的 str指向同一块内存,所以calss2=class1的str指向一块随机内存,在调用class2.showchar()时会随机输出。
输出结果如下:
constructor called
constructor called
string1
䁷䁷䁷䁷䁷
destrustor called
destrustor called
此外:
(class2=class1)=class3是不允许的,编译器不允许临时对象调用成员函数。
0 条评论