#include <iostream>
using namespace std;
class A
{
public:
int value;
A(int n) { value = n; }
A(A other) { value = other.value; }
void print()
{
cout << value;
}
};
int main()
{
A a(10);
A b= a;
b.print();
}
编译器会报错:
原因:若允许传入值,则在参数传递时会继续调用拷贝构造函数,形成无限递归。
解决方案:传入引用即可,A &other。
来自剑指offer p24。
重载“=”运算符:
using namespace std;
class A
{
public:
int value;
A(int n) { value = n; }
A(A &other) { value = other.value; }
void print()
{
cout << value;
}
A& operator=(const A &a)
{
this->value = a.value;
return *this;
}
};
int main()
{
A a(1);
A b = a;
A c=b=a;
c = b = a;
cout << b.value<<c.value;
}
返回值为A&:不为void是为了可以连续赋值;返回引用是为了防止返回对象,返回对象会调用构造函数和析构函数导致不必要的开销。
参数为const A&:const为了防止改变传进去的对象;传入引用是为了防止传参时调用构造函数,导致不必要的开销。
main函数中,A b=a调用的是拷贝构造函数,A c=b=a,b=a调用重载=函数,A c=b调用拷贝构造函数。c = b = a;调用两次重载运算符函数。
附:剑指offer上给出的代码:(重载=)
CMyString& CMyString::operator =(const CMyString &str)
{
if(this == &str)
return *this:
delete []m_pData;
m_pData = nullptr;
m_pData = new char[strlen(str.m_pData) + 1];
strcpy(m _pData, str.m _pData);
return *this;
}
先判断当前实例和参数是不是同一个,如果是同一个直接返回,因为下面有删除内存操作,若是同一个则当前实例的内存被释放,后续再也无法找到。
其次删除之前的内存,防止之前已经分配的内存没有释放导致内存泄漏。
delete []m_pData; 释放之前分配的内存
m_pData = nullptr;将指针置为空,若没有此步该指针为悬挂指针,指向已经释放了内存的地址,会报错。