Effective C++ 学习笔记——条款05:了解C++默默编写并调用的那些函数

C++自动生成的函数

在没有声明函数的情况下,编译器会为它声明构造函数、析构函数、copy构造函数、copy assignment操作符。以上函数均为 public 且 inline。
分别介绍每个函数(非常好!):https://blog.csdn.net/qq_41453285/article/details/88866596
例如:

class Empty();

则默认生成如下函数:

class Empty{
public:
    Empty() {...}                               // default构造函数
    Empty(const  Empty& rhs) {...}              // copy构造函数
    ~Empty() {...}                              // 析构函数
    Empty& operator= (const Rmpty& rhs) {...}   // copy assignment操作符
}

如上函数在被需要时,则会被编译器创建。如以下情况则会被创建:

Empty e1;       // default构造函数
                // 析构函数
Empty e2(e1);   // copy构造函数
e2 = e1;        // copy assignment操作符

但是这样的生成是有条件的

赋值运算符是为了将一个对象的成员数据拷贝进另一个对象中。对于赋值运算符,只有当代码合法而且有意义时,编译器才会自动生成。

如下代码就不满足该条件:

template<typename T>
class A{
  public:
    A(std::string& _name, const T& value);
  private:
    std::string& name;
    const T value;
};

对于如上的类,现在执行如下操作:

std::string s1("hello");
std::string s2("hi");

A<int> a1(s1,3);
A<int> a2(s2,6);
a1=a2;

存在问题:
C++规定引用是专一的,不允许引用被初始化后再指向另一个对象

而这样的操作就相当于:

int  a=3;
int& b=a;
int  c=7;
int& d=c;
b=d;           //编译器在此当然会报错

因此给a1对象的成员name的再赋值会导致编译出错。同样,C++也不允许为常量再赋值,因此对成员value赋值也会编译出错。

解决方法:
定义自己的赋值运算符!

此外,当基类有将赋值运算符声明为私有时,编译器也会拒绝为它的子类生成赋值运算符,因为在子类赋值过程中,它所包含的基类也应当被赋值。但是既然被声明为基类的私有成员,子类将不能调用。

总结:

如果自己不声明,编译器将会自动生成默认的构造函数,拷贝构造函数,拷贝赋值运算符和析构函数。

你可能感兴趣的:(Effective,C++学习笔记,c++)