构造/析构/赋值运算
Posted narjaja
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了构造/析构/赋值运算相关的知识,希望对你有一定的参考价值。
一、C++默认编写的函数
如果类中没有定义,程序却调用了,编译器会产生一些函数:
- default 构造函数
- copy 构造函数
- copy assignment 操作符
- 析构函数(non virtual)
所以写下:
class Empty { };
就好比写下:
class Empty {
public:
Empty(){ ... }
Empty(const Empty& rhs) { ... }
~Empty() { ... }
Empty& operator=(const Empty& rhs) { ... }
};
- 这些函数都是public且inline。
- 惟有当这些函数被需要(被调用),它们才会被编译器创建出来。
- 如果自己构造了构造函数(无论有无参数),编译器不会产生default构造函数。
- base class如果把拷贝构造函数或者赋值操作符设置为private,不会产生这两个函数。
- 含有引用成员变量或者const成员变量不产生赋值操作符。
- 编译器产生的析构函数是个non-virtual。
编译器可以暗自为类创建default构造函数、copy构造函数、copy assignment操作符,以及析构函数。
二、拒绝编译器自动生成函数
构造函数与析构函数是每一个类必须有的,但copy构造函数和copy assignment操作符对于某些类是不需要的需要明令禁止。
为了避免编译器自动生成copy构造函数和copy assignment操作符可以将其声明为private成员:
class Uncopyable{
private:
Uncopyable(const Uncopyable&);
Uncopyable& operator= (const Uncopyable&);
}
但类中成员函数和友元函数还是可以调用private函数,所以可以专门设计防止拷贝动作的基类(Boost也提供了这个类,名为noncopyable):
class nocopy : private Uncopyable {
...
}
派生类不再声明copy构造函数和copy assignment操作符。
如果不需要copy构造函数和copy assignment操作符要明令禁止,为驳回编译器自动(暗自)提供的机能,可将相应的成员函数声明为private并且不予实现。使用像noncopyable这样的基类也是一种做法。
三、为多态基类声明virtual析构函数
1.给多态基类应该主动声明virtual析构函数
如果多态基类析构函数没有加声明为virtual,当指向派生类对象的基类指针调用delete的时候,基类成分通常会被销毁,而派生类的成分可能还留在堆里。这可是形成资源泄漏、败坏之数据结构、在调试器上消费许多时间。2.非多态基类,不要声明virtual析构函数
当类不企图被当做基类的时候,不要令其析构函数为virtual。因为实现virtual函数,需要额外的开销(指向虚函数表的指针vptr)。
多态基类一般包含一个virtual函数,所以一个类里面有virtual函数则声明virtual析构函数,没有virtual则不声明virtual析构函数。
以上是关于构造/析构/赋值运算的主要内容,如果未能解决你的问题,请参考以下文章
C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读
C++类和对象(构造函数析构函数拷贝构造函数赋值运算符重载Const成员)详细解读