classCopy and operator=详解
在类中我们常常有一些可以不用写,就可以使用的函数,比如默认的构造函数,默认的copy构造,还有默认的操作符重载= 如下例所示:
#include<iostream>
class Test{/*这是一个空类*/};
int main(int argc,char**argv)
{
Test test1; //success: 这里调用了默认的构造函数
Test test2(test1); //success: 这里调用了默认的copy构造函数
test1=test2; //success:这里调用的是默认的操作符重载=
return 0;
}
上面的方法让我们很方便的省略一些事情,但是我们需要了解的是,什么时候这么写会出错,会出现什么问题。如下例所示:
#include<iostream>
class Test{
public:
Test(std::string& name,const int value):nameTemp(name),valueTemp(value){}
private:
std::string& nameTemp;
const int valueTemp;
};
int main(int argc,char**argv)
{
std::string oldname("老的");
std::string newname("新的");
Test test1(oldname,12); //success: 这里调用了自定义的构造函数
Test test2(newname,14); //success: 这里调用了自定义的构造函数
test1=test2; //error:调用操作符重载=发生错误
return 0;
}
错误解析:
- 这里使用了const属性,如果有常量属性的话默认的操作符重载=会出现问题(常量不可改变)
- 还有就是使用了reference,引用初始化后,不可修改
禁用默认的类函数和操作符重载
很多时候我们不需要用到这些特性,我们可以使用delete关键字,示例如下:
#include<iostream>
class Test{
public:
Test(std::string& name,const int value):nameTemp(name),valueTemp(value){}
Test(const Test&)=delete;
Test& operator=(const Test&)=delete;
private:
std::string& nameTemp;
const int valueTemp;
};
int main(int argc,char**argv)
{
std::string newname("新的");
Test test2(newname,14); //success: 这里调用了默认的copy构造函数
Test tes3(test2); //error: 这里的默认operator=已经没有了,所以报错
return 0;
}
如上图所示,我们也可以自定义这些操作
#include<iostream>
class Test{
public:
Test(std::string& name,const int value):nameTemp(name),valueTemp(value){}
Test& operator=(const Test&){/*自定义操作后返回*/}
private:
std::string& nameTemp;
const int valueTemp;
};
int main(int argc,char**argv)
{
std::string newname("新的");
Test test2(newname,14); //success: 这里调用了默认的copy构造函数
Test tes3=test2; //success: 这里是自定义的operator=
return 0;
}