• 【C++11新特性】=default 和 =delete


    1.四种特殊的成员函数

    C++ 的类有 4 种特殊的成员函数,分别为默认构造函数、析构函数、拷贝构造函数、拷贝赋值运算符。这些类的特殊成员函数负责创建、初始化、销毁、拷贝类的对象。

    如果程序员没有显式地为一个类定义某个特殊成员函数,而又需要用到该特殊成员函数时,则编译器会隐式地为这个类生成一个默认的特殊成员函数。

    #include 
    using namespace std;
    
    class X
    {
    private:
    	int a;
    };
    
    int main()
    {
    	X x; // 可以编译通过,编译器隐式生成默认构造函数
    
    	return 0;
    }
    

    如果在 X 中显式地自定义了非默认构造函数,却没有定义默认构造函数,下面的代码会出现编译错误。

    #include 
    using namespace std;
    
    class X
    {
    private:
        int a;
    public:
        X(int i)
        {
            a = i;
        }
    };
    
    int main()
    {
    	X x; // 错误,默认构造函数X::X()不存在
    
    	return 0;
    }
    

    为了解决上面的问题,我们需要自定义默认构造函数,如下代码所示。

    #include 
    using namespace std;
    
    class X
    {
    private:
        int a;
    public:
        X() {}; // 手动定义默认构造函数
        X(int i)
        {
            a = i;
        }
    };
    
    int main()
    {
    	X x; // 正确,默认构造函数X::X()存在
    
    	return 0;
    }
    

    但是手动编写存在两个问题:

    • 程序员工作量变大;
    • 没有编译器自动生成的默认特殊成员函数效率高。

    2.=default

    为了解决上述的两个问题,C++11 标准引入了一个新特性:=default 函数。

    程序员只需在函数声明后加上 =default;,就可将该函数声明为 =default 函数,编译器将为显式声明的 =default 函数自动生成函数体。

    #include 
    using namespace std;
    
    class X
    {
    private:
        int a;
    public:
        X() = default; // 该函数比用户自己定义的默认构造函数获得更高的代码效率
        X(int i)
        {
            a = i;
        }
    };
    
    int main()
    {
    	X x; // 正确,默认构造函数X::X()存在
    
    	return 0;
    }
    

    =default 函数特性仅适用于类的特殊成员函数,且该特殊成员函数没有默认参数。

    class X
    {
    private:
        int a;
    public:
        int f() = default; // 错误,函数f()不是类X的特殊成员函数
        X(int) = default; // 错误,构造函数X(int)不是类X的特殊成员函数
        X(int i = 1) = default; // 错误,默认构造函数X(int i = 1)含有默认参数
        X() = default; // 正确
    };
    

    =default 函数既可以在类体内定义,也可以在类体外定义。

    class X
    {
    public:
        X() = default; // 默认构造函数,类体内定义
        X(const X&); // 拷贝构造函数,类体外定义
        X& operator = (const X&); // 拷贝赋值运算符,类体外定义
        ~X() = default; // 析构函数,类体内定义
    };
    
    X::X(const X&) = default; // 类体外定义
    X& X::operator = (const X&) = default; // 类体外定义
    

    3.=delete

    为了能够让程序员显式地禁用某个函数,C++11 标准引入了一个新特性:=delete 函数。

    程序员只需在函数声明后加上 =delete;,就可将该函数禁用。

    • 必须在函数第一次声明的时候将其声明为 =delete 函数。

    • 不同于 =default=delete 没有限制为特殊成员函数才能使用 =delete

    class X
    {
    public:
    	X();
    	X(const X&) = delete;  // 禁用拷贝构造函数
    	X& operator = (const X&) = delete; // 禁用拷贝赋值运算符
    };
    

    =delete 函数特性还可用于禁用类的某些转换构造函数,从而避免不期望的类型转换。

    class X
    {
    public:
    	X(int) = delete;
    };
    

    =delete 函数特性还可以用来禁用某些用户自定义的类的 new 操作符,从而避免在自由存储区创建类的对象。

    class X
    {
    public:
    	// 禁止使用者在堆上申请对象
    	void* operator new(size_t) = delete;
    	void* operator new[](size_t) = delete;
    };
    
  • 相关阅读:
    MySQL 数据库 - 通用语法 DDL DML DQL DCL
    超全详细,解决校园网没有路由器实现开发板和虚拟机直连
    BIO、NIO、AIO
    C++零基础教程(引用)
    X86函数调用模型分析
    ORACLE的分区(一)
    移动测试之语音识别功能如何测试?
    年轻人为什么不看百趣代谢组学2022年高分项目文章精选集锦
    点击化学试剂DBCO-PEG-PLL 二苯并环辛炔-聚乙二醇-聚赖氨酸
    【Python】通过Fourier变换实现频域滤波
  • 原文地址:https://blog.csdn.net/qq_42815188/article/details/127085197