第十八章 c++新标准

auto

 

是一个存储类型说明符,用于实现自动类型推断。

auto maton = 112;// int

auto pt = &maton // int *

for(std::initializer_list<double>::iterator p = il.begin(); p!=il.end(); p++) {
}

for(auto p = il.begin(); p!=il.end(); p++) {
}

decltype

将变量的类型声明为表达式指定的类型

decltype(x) y;//让y的类型与x相同,其中x是一个表达式。

double x;
int n;
decltype(x*n) q; //q 是double类型
decltype(&x) q; //pd 是&x,double*型

通常用在模板里
template<typename T, typename U>
void ef(T t, U u) {   
    decltype (T*U) tu;
}

返回类型后置

新增函数声明语法,在函数名和参数列表后面(而不是前面)指定返回类型。

double f1(double, int);

auto f2(double, int) -> double;

模板别名:using = 

using itType = std::vector<std::string>::iterator;

可以用于模板部分具体化:
template<typename T>
using arr = srd::array<T, 12>;

nullptr: 空指针

基于范围的for循环:

for(double x : prices) {

}

for (auto x : prices) {

}

如果要修改容器中的每个元素,可以用引用类型
std:vector<int> vi(6);
for (auto &x : vi) {
    x = std::rand();
}

右值引用

左值引用:可以出现在赋值语句的左边,int & rn = n;

右值引用:使用&&表示,可以关联到右值,即可以出现在赋值表达式的右边,但不能对其应用地址运算符的值。

int x = 10;
int y = 23;
int && r1 = 13;
int && r2 = x + y;
r2 关联到的是当时x+y计算的结果,即r2关联的是23,即使以后修改了x或者y,也不会影响到r2.

 将右值关联到右值引用,会导致该右值存储到特定的位置,且可以获取到该位置的地址。也就是虽然不能用于&13,但是可以用&r2。

移动语义和右值引用

std::move() 可以强制将左值移动为右值

Useless one(10, ‘x’);
Useless  four = std::move(one);
one是一个左值,但通过std::move(one) 变成右值,将调用移动构造函数。
Useless & Useless::operator=(Useless && f) {
}

默认方法和禁用方法

default

如果提供了某个构造函数,编译器将不会自动自动默认的构造函数。例如提供可一个构造函数,编译器将不会再提供默认构造函数,复制构造函数,移动构造函数等。

如果想用编译器提供的构造函数,可以使用default关键字

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

编译器将创建在没有提供默认构造函数的情况下,自动提供构造函数。

delete

用于禁止编译器使用特定的方法,例如禁止复制对象,可禁用复制构造函数和复制赋值运算符。

把方法放到private,能达到相同的目的。

class Someclass {
public:
    Someclass(Someclass &&);
    Someclass() = default;
    Someclass(const Someclass &)  = delete; //禁用复制构造函数
    Someclass & operator = (const Someclass &)  = delete;    
}

 管理虚方法:override 和 final

override

如果子类重写了父类函数,但是特征标不一样,将隐藏父类方法。

例如:

class Action {
    int a 
public:
    Action(int i = 0): a(i) {}
    int val() const {return a;}
    virtual void f(char ch) const {std::const << val() << ch << "\n";}
}

class Bingo : public Action {
    int a 
public:
    Bingo (int i = 0): Action(i) {}
    virtual void f(char * ch) const {std::const << val() << ch << "\n";}
}

由于子类Bingo定义f(char * ch) 而不是f(char ch), 将对Bingo对象隐藏f(char ch);将导致程序不能使用下边代码:

        Bingo b(10);
        b.f('@'); //不被允许,因为父类方法f(char) 被隐藏

说明符override指出,程序将覆盖一个虚函数,如果声明与父类方法不匹配,编译器将报错。

virtual void f(char * ch) const override {
    std::cout << val() << ch << "!\n";
}
编译器将报错

final:

禁止编译器覆盖特定的虚方法。

virtual void f(char  ch) const final {
}
将禁止Action 的派生类重新定义函数f()

Lambad函数(匿名函数)

[&count] (int x) {
    count + = (x % 13 == 0);
}

[] (int x) {return (x % 13 == 0);}

[]相当于函数名,没有声明返回类型,编译器会像decltyp一样,自动推断返回类型

count3 = std::count_if(numbers.begin(), numbers.end(), 
                        [] (int x) {return x % 3 == 0;});

lambda可以访问作用域内的任何动态变量,要捕获要使用的变量,可以将器名称放在中括号内,如果只指定了变量名[z], 将按值访问变量;如果在名称前加上&,[&count] 将按引用访问变量。

也可以多个[ted, &ted]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值