美文网首页
C++11新的类功能

C++11新的类功能

作者: 艰默 | 来源:发表于2023-02-14 09:13 被阅读0次

文章首发公众号:iDoitnow

1. 特殊的成员函数

C++11在原有的4个特殊成员函数(默认构造函数、复制构造函数、复制赋值运算符和析构函数)的基础上新增了移动构造函数和移动赋值运算符。这些特殊成员函数在各种情况下是会通过编译器自动提供的。

  • 默认构造函数:如果未定义任何构造函数,编译器将提供一个默认构造函数,对于类成员则调用其默认构造函数(对于内置的成员,默认构造函数不对其进行初始化。如果使用者提供了移动构造函数,编译器将不会自动提供默认构造函数)。
  • 复制构造函数:如果未定义复制构造函数,而代码有需要使用它,编译器将提供一个默认的复制构造函数。(如果使用者提供了类的移动构造函数的情况下,编译器将不会自动提供复制构造函数)
  • 移动构造函数:如果未定义移动构造函数,而代码有需要使用它,编译器将提供一个默认的移动构造函数。(如果使用者提供了类的析构函数、复制构造函数、复制赋值运算符或移动赋值运算符的情况下,编译器将不会自动提供移动构造函数)
  • 复制赋值运算符:如果未定义复制赋值运算符,而代码有需要使用它,编译器将提供一个默认的复制赋值运算符。(如果使用者提供了移动赋值运算符,编译器不会自动提供复制赋值运算符)
  • 移动赋值运算符:如果未定义移动赋值运算符,而代码有需要使用它,编译器将提供一个默认的移动赋值运算符。(如果使用者提供了复制构造函数、移动构造函数、复制赋值运算符或析构函数,编译器不会自动提供移动赋值运算符)

当用户在定义某些特殊函数后,导致另外某个特殊函数不会自动创建,这时候用户仍可以使用关键词 default 强制编译器生成隐式声明的目标特殊成员函数函数。例如用户定义了移动构造函数,编译器不会自动构建默认构造函数、复制构造函数和复制赋值运算符,这种情况下我们可以通过default强制编译器创建这些方法的默认版本:

class A{
    public:
    A(A &&);
    A() = default;
    A(const A&) = default;
    A & operator = (const A&) = default;
};

同时,有些时候,我们不希望编译器为我们提供某个特殊的成员函数默认版本,我们可以使用关键字delete来禁止编译器使用特定方法。关键字default只能用于这个6个特殊的成员数(默认构造函数、复制构造函数、复制赋值运算符、移动构造函数、移动赋值运算符和析构函数),但delete可以用于任何成员函数。例如:

class A{
    public:
    A() = delete;//禁止编译器生成默认构造函数
    void readDoubleNum(double);
}

class B{
    public:
    B() = delete;//禁止编译器生成默认构造函数
    void readDoubleNum(double);
    void readDoubleNum(int) = delete;//禁用readDoubleNum函数的特定转换
};

A a;
a.readDoubleNum(5.0);//正确
a.readDoubleNum(5);//正确,int值5将被转换为5.0,进而执行readDoubleNum(double)方法

B b;
b.readDoubleNum(5.0);
b.readDoubleNum(5);//错误,其与readDoubleNum(int)原型匹配,编译器检测到该方法被禁用后,在编译阶段就会报错,防止int到double的特定转换

2. override和final

  • override标识符

    override说明符的作用是用来指定一个虚函数覆盖另外一个虚函数。其用法如下:

    class A{
        virtual void fun();
        ...
    };
    
    class B : A{
        void fun() override;//B::fun将覆盖A::fun
        ...
    };
    

    C++11引入override标识符的目的就是为了在重写基类的方法时候,防止重写方法的类型、名称和参数列表因为人为因素造成其与基类的不一致,无法使用多态。使用override标识符将重写的检查工作(重写方法的类型、名称和参数列表要与基类的保持一致)交给编译器处理,减少人为出错的可能。

  • final标识符

final标识符的作用是指定某个虚函数不能在派生类中被覆盖,或者某个类不能被派生。其使用方法如下:

calss A{
    virtual void fun();
};

class B : A{
    void fun() final;//A::fun被覆盖,而且B::fun是最终被覆盖函数
    void ba() final;//错误,ba非虚函数,因此它不能是final
};

class C final: B{//C为final
    void fun() override;//错误,fun不能被覆盖,因为其在B中为final
};

class D : C{};//错误,因为类C位final,其不可以被派生

参考文献

C++ Primer Plus(第六版) - 第18章 探讨C++新标准
C++ 参考手册

相关文章

  • Python类的继承

    什么是继承 新类不必从头编写 新类从现有的类继承,就自动拥有了现有类的所有功能 新类只需要编写现有类缺少的新功能 ...

  • C++11风格的新元素

    “C++11就像一门新的语言。” – Bjarne Stroustrup C++11标准推出了很多有用的新特性,本...

  • 《深入理解 C++11 :C++11 新特性解析与应用》国内首本

    深入理解 C++11 :C++11 新特性解析与应用 公众号回复“41532”获取下载地址 《深入理解C++11:...

  • 继承

    继承 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,...

  • C++11部分特性

    预定义宏 1. func预定义标识符 功能:返回所在函数的名字C++11中甚至允许在类或结构体中使用: 原理:编译...

  • [C++11阅读][1-1-1]新标准设计思想和特性概述

    读《深入理解C++11:C++11新特性解析与应用》 虽然设计C++11的目的是为了要取代C++98/03,不过相...

  • 阿里巴巴面试题基础篇 C++11

    ● 请问C++11有哪些新特性? 参考回答: C++11 最常用的新特性如下: auto关键字:编译器可以根据初始...

  • 熟悉的c++,你还认识么?

    你该关注C++11吗? 很明显,C++11为C++带来了大量的新特性。C++11将修复大量缺陷和降低代码拖沓,比如...

  • C++11 新特性之类型推断与类型获取

    以前我写过关于c++11新特性的第一部分,这是C++11新特性介绍的第二部分,涉及到C++11这次更新中较为重要的...

  • 继承

    一种类与类之间的关系 利用一种已存在的类作为基础建立新类 新类的定义可以增加新的数据或功能,也可以用父类的功能,但...

网友评论

      本文标题:C++11新的类功能

      本文链接:https://www.haomeiwen.com/subject/eomskdtx.html