class Test
{
public:
Test();
~Test();
Test(const Test&);
Test& operator=(const Test&);
Test* operator&();
const Test* operator&()const;
Test(Test&&);
Test& operator=(Test&&);
};
在c11之后,类中总共有8个默认函数,其中
移动拷贝:Test(Test&&)
移动赋值:Test& operator=(Test&&)
都是在c11之后才新添加的。
1.构造函数
作用:
1.给对象所在的内存空间做初始化,创建对象。
2.类型转换
特点:
1.可以根据实际需要进行缺省的,或者重载
2.不依赖对象,对象无法调用,只能在对象定义点调用
2.析构函数
1.不可重载,对象销毁时会调用析构函数,并释放空间
2.依赖对象,可以通过this->~Test()来调用,但是不建议,如果手动调用最后可导致析构函数重复调用,导致程序崩溃。
3.拷贝构造函数
作用:拿一个已存在的对象再来生成相同类型的新对象。
注意:类中默认提供的拷贝构造函数为浅拷贝构造,如果对象申请了系统资源的话,则需要我们自己重写它。
4.赋值运算符重载函数
作用:拿一个已存在的对象给一个已存在的该类型对象进行赋值
实现步骤:
浅拷贝的实现
class Test
{
public:
Test(int value =0) :value_(value) {}
Test& operator=(const Test& test)
{
if (this != &test)
{
value_ = test.value_;
}
return *this;
}
private:
int value_;
};
深拷贝的实现:
class Test
{
public:
Test(int value):value_(new int(value)){}
Test& operator=(const Test& test)
{
if (this != &test)
{
delete value_;
value_ = nullptr;
value_ = new int(*(test.value_));
}
return *this;
}
private:
int* value_;
};
1.自赋值判断 防止是自己给自己赋值,假如说是自己给自己赋值的话,如果没有这一步判断,我们按照上面的代码走,先delete value_,然后再执行到new int(*(test.value_));时,此时要解引用test的value_,此时因为已经为nullptr,此时就会程序崩溃。
2.释放旧资源
3.生成新资源
因为对象申请了系统资源,所以需要深拷贝,此时对新对象也要申请系统资源。
4.赋值
注意:
为什么要以引用返回
1.为了更好的拟合内置类型。
c++是由四部分组成:1.c,2.c++的对象特性,3.template c++,4.STL,所以对于c++来说,也要拟合于c,即意思是,尽可能的贴近或者模仿它的内置类型,比如当我们使用int时,定义三个int 变量a,b,c,当我们进行a=b=c;时,实际是通过c这个对象本身赋值给b,然后通过b这个对象本身赋值给a,赋值的时候并没有产生匿名对象。
2.为了减少一个匿名对象的构造,效率更高
好多人说为什么要以引用而不是值返回的时候,说的是使用引用的话可以实现 a=b=c这种连等,但实际是,当我们以值返回时也可以达到这种目的。
当我们以值返回时,生成一个匿名对象(将亡值),接着由这个匿名对象对其赋值b赋值(调用的是b的赋值重载),对a也是同理的。
5.一般对象取地址函数
Test* operator()
{
retrun this;
}
6.常对象取地址函数
const Test* operator&()const
{
return this;
}
7.移动拷贝
作用:把一个对象的资源转移给另外一个对象,减少了对资源的扰动(对资源的释放又申请)
使用场景:把将亡值对象的资源继续给其它对象使用。
Test (Test&& test):value_(test.value_)
{
test.value_ = nullptr;
}
8.移动赋值
作用:把一个对象的资源转移给另外一个对象,减少了对资源的扰动(对资源的释放又申请)
Test& operator=(Test&& test)
{
if (this != &test)
{
value_ = test.value_;
test.value_ = nullptr;
}
}