c++11标准的新特性

c++11 标准的特性总结

c++引入了很多新特性,我这里列举了一些我觉得很好的特性. 后续可能再补充其它.

default 与 delete关键字

  1. 当我们想让编译器生成默认的构造函数或赋值运算符时,我们可以使用default关键字指示编译器生成. 要注意几点:

    • defalut关键字只能指示编译器可以默认生成的函数,例如构造与赋值操作符.
    • default关键字可以在函数声明的时候使用,此时默认为内联的.也可以在函数定义的时候使用,此时为非内联的.
  2. delete关键字指示哪些函数是删除掉的,不能使用. 应用场景:例如实现单例时,会把构造函数声明为private, c++11之后更好的办法是使用delete来指示. 要注意的问题:

    • delete关键字必须在类成员函数声明的时候使用.
    • delte不仅仅可以指示类的构造函数,也可以指示普通的类成员函数.
    • 析构函数不可以是私有的, delete关键字同样不可以修饰析构函数.

auto关键字

使用auto关键字,可以让编译器自动推导变量类型. auto自动推导的原则我有至今有点迷惑, 有几条原则:

  • 自动推导时,auto关键字会忽略指针掉顶层的const, 也就是指针本身的const.
  • auto关键字自动推导时,不会自动推导为引用类型,如果想让它是引用类型,你自己要加上 &.

emplace操作

emplace()/empalce_front()/empalce_back()三个操作对应了insert()/insert_front()/insert_back()操作, 不同之处是: inert是进行拷贝操作,而emplace是直接在容器的内存空间中进行构造一个对象. 这可以提高代码的运行效率, 避免不必要的copy操作. 例如:

class A {
public:
    A(int a, int b) {
        cout << "构造!" << endl;
    }

};

int main()
{
    vector<A> a;
    a.emplace_back(1, 2);
    a.push_back(A(1, 2));
    return 0;
}

explicit 关键字

该关键字还是非常有用处的.很多时候,我们不希望类对象执行隐式的类型转换,我们就可以使用explicit关键字修饰的构造函数或者类型转换重载函数. 特别说明两人点:

  • 当表达式被作用于条件时,编译器会将显式的类型转换自动应用于它, 比如用于if/while语句时. 意思就是此时进行了隐式类型转换.
  • explicit关键字只能用于修饰构造函数或类型转换运算符.

final关键字

它即可以用于修饰类,也可以用于修改类的虚函数. 1. 当用于修饰类时,想表示该类不能被继承,它不能作为基类. 当用于修饰虚函数时,想表示该虚函数不能在子类中被重写. 这个关键字还是很有价值的,增加代码可读性,也可以让编译器给你作检查.

override关键字

该关键字用于修饰子类中重写父类的虚函数,表明此时的虚函数是继承自父类的. 该关键字也很好,可以避免父类虚函数名修改掉而漏修改相应子类虚函数的情况,因为编译器会给你报错的.

lambda表达式

之前总结过,见此处;

智能指针

之前也总结过,见此处

右值引用与std::move

c++11中引入了右值引用的概念, 我觉得引入它的目的就是进行对象的移动而非拷⻉.. 有了右值引用, 我们就可以字义类的移动构造函数与移动赋值运算符,有了它们,我们就可以使用std::move(对象)进行移动而非拷贝操作了. 该特性很实用,能操作效率.

  • 如果一个对象支持移动操作,它肯定定义的相应的移动构造函数和移动赋值运算符, 那么使用std::move()对类对象进行赋值或移动操作时, 就会调用它们. 如果类没有定义,使用std::move操作时,还是会调用拷贝构造与赋值运行符.

  • 当我们定义移动构造与移动赋值运行符时,一定要尽可能加上noexcept关键字. 否则的话, STL中的容器在操作对象时,很可能还是使用拷贝还非移动,例如:vector, 假如一个vector现在的元素为4个,capicity也等于4, 当添加第5个元素时, vector分另分配一块内存并把原来的4个元素搬到新内存位置.如果你定义的对象的移动构造函数没有加noexcept关键字,则STL在操作时会使用拷贝而非移动,目的是确保在抛出异常时,原始数据不变.

类内初始值

c++11之前,不是支持在声明类成员数据的同时进行初始化的, 只能使用初始化列表或初始化函数. c++11之后,可以支持类内成员变量在声明的同时进行初始化了,真的很方便,大大减少了构造函数初始化列表的长度以及简化了函数体. 真的很方便的.
注意一点:类内初始值必须使用=的形式花括号括起来的直接初始化形式.

异常

noexcept 关键字表示函数不抛出异常.

待补充

posted @ 2020-09-05 22:24  殷大侠  阅读(388)  评论(0编辑  收藏  举报