Effective C++条款05:构造/析构/赋值运算之(了解C++默默编写并调用哪些函数)

一、C++类默认定义的函数

  • 如果class没有定义构造函数、析构函数、拷贝构造函数、拷贝赋值运算符函数,那么C++内部会动创建一个默认的构造函数、析构函数、拷贝构造函数、拷贝赋值运算符函数。并且这些默认函数都是public且inline的

演示说明

class Empty{}; //空类

Empty e1;    //调用e1的默认构造函数
Empty e2(e1);//调用e2的默认拷贝构造函数
e2 = e1;     //调用e2的默认拷贝赋值运算符

//程序结束
//调用e1与e2的默认析构函数

二、默认构造函数、默认析构函数做了什么?

  • 默认构造函数与默认析构函数主要是给编译器一个地方用来防止“隐藏幕后”的代码,像是调用基类和非静态成员变量的构造函数和析构函数
  • 注意:编译器定义的默认析构函数是非virtual的,除非这个class的基类自身有virtual析构函数(这种情况下这个函数的虚属性(virtual)来自于基类)

三、默认拷贝构造函数、默认拷贝赋值运算符做了什么?

  • 默认拷贝构造函数/默认拷贝赋值运算符一样,都是在拷贝/对象赋值时将类的每一个非静态成员变量逐个拷贝到目标对象之中

拷贝构造示案例

template<typename T>
class NamedObject
{
public:
    //两个构造函数
	NamedObject(const char* name, const T& value);
	NamedObject(const std::string& name, const T& value);

private:
	std::string name;
	T objectValue;
};

NamedObject<int> no1("dongshao", 2);
NamedObject<int> no2(no1);  //调用NamedObject<int>的默认拷贝构造函数
  • 上面的no2对象调用默认的拷贝构造函数来拷贝no1对象,其中的操作有:
    • 将no1对象的name数据成员拷贝给no对象的name数据成员(又因为name为string类型,所以最终会调用string的拷贝构造函数来拷贝name)
    • 因为此程序中模板类型为int,所以objectValue为int内置类型,直接将no1对象的objectValue赋值给no2的objectValue
  • 对于赋值运算符来说,其与拷贝构造函数一样,也是逐个将数据成员进行重新赋值

拷贝赋值运算符的错误注意事项

  • 虽然拷贝构造函数与拷贝赋值运算符用起来比较类似,但是有一种情况会导致出错,见下面的演示案例
template<typename T>
class NamedObject
{
public:
    //因为name变为了string引用类型,因此参数1位char*类型的构造函数就没有用了
	NamedObject(std::string& name, const T& value);

private:
    //此处将name改为了引用形式,objectValue改为了const类型
	std::string& name;
	const T objectValue;
};


std::string newDog("Persephone");
std::string oldDog("Satch");
NamedObject<int> p(newDog, 2);
NamedObject<int> s(oldDog,36);

p = s; //错误
  • 上述“p=s”错误的原因:
    • name:因为name为引用类型了,我们知道引用一旦绑定就不可以改变引用指向,但是在此处拷贝赋值运算符中,我们将p的name引用从一开始指向于newDog又指向了oldDog,因此会发生错误
    • objectValue:因为objectValue为const类型,因此在初始化之后其值就不可以改变了,此处将p的值从2改变为36因此会发生错误

四、拒绝生成默认函数

  • 从“三”中的演示案例可以看到,在某些情况下,使用了系统提供的默认拷贝赋值运算符会出现错误。因此有些情况下我们不希望使用class提供的默认拷贝赋值运算符,那么就需要提供一种方法
  • 如果一个基类将拷贝赋值运算符声明为private,那么编译器就拒绝为派生类生成默认的拷贝赋值运算符。因为基类如果想使用这些函数,那么这些函数会相应的处理基类成份,但是基类是private的,所以不可以使用
  • 这种方法不仅适用于拷贝赋值运算符,对于构造函数、拷贝构造函数都同样有效
发布了1399 篇原创文章 · 获赞 958 · 访问量 31万+

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/104165762