C++11新特性(也称c++2.0)

目录

1.输出C++版本:cout << __cplusplus << endl;

2.Uniform Initialization(一致性初始化)

3.initializer_list(形参)

4.explicit

5.for循环的新用法

6.default和delete

7.Alias Template(模板化名)

8.模板模板参数

9.Type Alias(类型化名)

10.using的用法

11. 关键字 noexcept,override,final

12.decltype

13.Lambda(匿名函数)


1.输出C++版本:cout << __cplusplus << endl;

#include <iostream>

int main()
{ 
	cout << __cplusplus << endl;
	system("pause");
	return 0;
}

老版的话会输出199711,支持c++11的话会输出201103

注:visual studio要手动打开c++11,在“解决方案资源管理器”右键自己的项目, 如“侯捷C++”(是总项目,不是项目中的某一头文件或源文件),按一下操作

【右击项目】–【选择属性】–【C/C++】–【语言】–【C++语言标准】,选择想要的标准即可

visual studio2019以上才支持C++11(好像是)

2.Uniform Initialization(一致性初始化)

C++在定义容器时,有的使用小括号,有的使用中括号,有的使用大括号,C++11及以后,统一使用大括号

#include <iostream>
#include <vector>
#include <complex>
using namespace std;

int values[] { 1,2,3 };
vector<int> v { 1,2,3 };
vector<string> cities {"beijing","shanghai","guangzhou"};
complex<double> c { 4.0, 3.0 };  //等价于 complex<double> c(4.0, 3.0);

3.initializer_list(形参)

如果函数的实参类型都相同 ,但个数不确定,使用initializer_list做形参,后面跟数据类型,如int,string等,initializer_list好像相当于链表

void printX(initializer_list<int> v1)
{
	for (auto p = v1.begin(); p != v1.end(); ++p) {
		cout << *p << typeid(p).name()  << endl;	
	}
}

printX({1,2,3}); //函数调用

4.explicit

 explicit 是一个关键字,用于修饰类的构造函数。当一个构造函数被声明为 explicit 时,它指定该构造函数不能用于隐式类型转换。这意味着在使用该构造函数创建对象时,必须使用显式的方式,而不能依赖于隐式的类型转换。

#include <iostream>

class MyClass {
public:
    explicit MyClass(int x) {
        value = x;
    }

    void printValue() {
        std::cout << "Value: " << value << std::endl;
    }

private:
    int value;
};

int main() {
    // 使用 explicit 构造函数的显式方式创建对象
    MyClass obj1(10);
    obj1.printValue();

    // 下面这行代码将会导致编译错误,因为构造函数是 explicit 的
    // MyClass obj2 = 20;  // 错误:不能进行隐式类型转换

    // 必须使用显式方式
    MyClass obj3 = MyClass(20);
    obj3.printValue();

    return 0;
}

5.for循环的新用法

for(decl : coll){   // decl为声明,coll为容器
    statement
}

示例1
for (int i : {1, 2, 3}) {
	cout << i << endl;
}

示例2
vector<string> v1{ "beijing","shanghai","guangzhou" };
for (auto s : v1) {
	cout << s << endl;
}

6.default和delete

 default:在类中,如果你自行定义了一个构造函数,那么编译器就不会再给你一个默认的构造函数了,如果你在默认的构造函数上强制加上=default,就可以重新获得并使用默认的构造函数

delete:关键字用于禁用某个特殊成员函数。通过在声明中使用 delete,你可以阻止编译器生成相应的函数,或者禁止使用某个函数。

class MyClass {
public:
    // 显式使用默认构造函数
    MyClass() = default;

    // 使用默认的拷贝构造函数
    MyClass(const MyClass&) = default;

    // 使用默认的析构函数
    ~MyClass() = default;
};


class NonCopyableClass {
public:
    // 禁用拷贝构造函数
    NonCopyableClass(const NonCopyableClass&) = delete;

    // 禁用拷贝赋值运算符
    NonCopyableClass& operator=(const NonCopyableClass&) = delete;
};

7.Alias Template(模板化名)

      模板化名,就是给模板起别名,使用using关键字,这个别名就代表那个容器,这个别名是支持传入参数的,即容器要放的数据类型,define和typedef不能代替模板化名,因为他们不支持传参

template <typename T>
using Vec = vector<T, allocator<T>>;  //allocator<T>为分配器,一般可以省略
Vec<int> v1{2,3,5};

8.模板模板参数

模板中的参数类型T也可以是模板,如下:

template <typename T,template<class,T> class Container>
class my_class {
    ...
};

 模板中的某个参数是模板,上图中第二行尖括号里的class后面的T省略了。当模板中的第二个参数是与第一个参数有关时,如上图,第二个参数是类模板,此时模板化名就派上用场了

9.Type Alias(类型化名)

 类型化名,就是给类型起了一个别名,使用using关键字,此时完全等价于typedef,如下图左上角,都代表指向函数的指针,右下角都代表T为value_type类型 

10.using的用法

c++中using主要有三大用法

第一类 用在打开标准库 如 using namespace std;
第二类 如下图我们类中的成员属性是Base中的,后面类中再出现此属性,就不用写Base::
第三类 就是我们刚才讲的模板化名和类型化名

11. 关键字 noexcept,override,final

 1.noexcept():用在函数或成员函数后面,如果后面括号里的东西为真的话,此函数不会报错,如果省略括号,表示没有条件,此函数不会报错

2.override,final

override(重写):放在函数后面,告诉我们是重写这个函数,而不是重新定义一个函数

如下图,我们在父类中Base中有一个虚函数vfunc,我们在子类Derived1中想要重写这个虚函数,但是不小心把float写成了int,此时是重新定义了一个虚函数vfunc,相当于函数重载,但当我们后面加上override,如类Derived2中,告诉编译器我们是重写虚函数,此时如果不小心写错,如把float写成int,编译器会报错来提醒我们。

虚函数 参考:C++虚函数详解-CSDN博客

final:写在类后面,这个类是继承体中的最后一个,不能有别的类来继承他;写在成员函数后面,该成员函数不能被继承,但是该成员函数所在的类可以被继承

12.decltype

让编译器根据表达式推断出类型

int x = 5;
decltype(x) y = 10; // 使用 decltype 获取 x 的类型,并将其应用于变量 y

map<string,float> coll;
decltype(coll)::value_type elem;    //等价于 map<string,float>::value_type elem;
注:每个容器都有value_type

与auto区别: decltype是C++11新增的一个关键字,和auto的功能一样,用来在编译时期进行自动类型推导。引入decltype是因为auto并不适用于所有的自动类型推导场景,在某些特殊情况下auto用起来很不方便,甚至压根无法使用。

auto varName=value;
decltype(exp) varName=value;

1. auto根据=右边的初始值推导出变量的类型,decltype根据exp表达式推导出变量的类型,跟=右边的value没有关系
2.auto要求变量必须初始化,这是因为auto根据变量的初始值来推导变量类型的,如果不初始化,变量的类型也就无法推导,而decltype不要求,因此可以写成如下形式  

decltype(exp) varName;

13.Lambda(匿名函数)

参考:C++ Lambda表达式详解-CSDN博客

 其中mutable(可变的),throwspec(抛出异常),return-type(返回值)为可选参数,这三个只要有一个写了,参数列表的括号就不能省略,即使没有参数

1. [ ] 捕获列表:[]是Lambda引出符。编译器根据该引出符判断接下来的代码是否是Lambda函数,捕获列表能够捕捉上下文中的变量以供Lambda函数使用。

[x,&y]:x为值传递,y为引用传递,如果是值传递,自身这个值的是不受外界变化所影响的,如下图中上左这段代码;如果是地址传递,两者会相互影响,如下图中上中这段代码。

[=]:表示默认接受外界所有的变量

2.mutable 可变的:表示捕获的外界变量此匿名函数是否对其可以改变,如++,如省略,表示不可改变

3.throw() 抛出异常:

4.return-type 返回值类型:如果省略表示此匿名函数不需要返回值

 

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值