[C++11/14 新特性] Range、default、delete和using关键字

目录

一、auto关键字用于遍历操作

二、default和delete关键字

三、using关键字

一、auto关键字用于遍历操作

auto关键字搭配for循环使用 可以让代码非常简洁和清晰
例如:
for(decl : coll)
{
    statement
}

代码示例:

#include <iostream>
#include <initializer_list>
#include <vector>

/*
auto关键字搭配for循环使用 可以时代码非常简洁和清晰
例如:
for(decl : coll)
{
    statement
}
*/
int main()
{
    for(int i : {2, 3, 5, 7, 9, 13, 17, 19})
    {
        std::cout << i << " ";
    }
    std::cout << std::endl;

    std::vector<double> vec {2.0, 3.2, 2.5, 7.8, 9.1, 10.3};
    for(auto elem : vec)
    {
        std::cout << elem << " ";
    }
    std::cout << std::endl;

    // 当加上&时 我们知道 相当于给变量取了别名 此时可以对vec中的元素进行改变
    for(auto & elem : vec)
    {
        elem *= 3;
        std::cout << elem << " ";
    }

    return 0;

}

运行结果:

二、default和delete关键字

在C++的类中,有四类特殊的成员函数:
1.默认构造函数;2.拷贝构造函数;3.拷贝赋值函数(operator=);4.析构函数;
它们控制着类的实例的创建、初始化、拷贝以及销毁,关键字 =default 和 =delete 在这四类特殊成员函数中的应用

默认构造函数:如果对构造函数进行了重载,则编译器不会隐式的生成一个默认的构造函数,此时如果调用了默认构造函数会在编译时报错,为了避免这种情况,一般会选择重写默认构造函数,且函数体为空。关键字 =default 优化了这种行为,用该关键字标记重写的默认构造函数,编译器会隐式生成一个版本,在代码更加简洁的同时,编译器隐式生成的版本的执行效率更高。

拷贝构造函数 和 拷贝赋值函数:不论有没有对它们进行重载,编译器始终会隐式生成默认版本,但有的时候不希望类实例进行拷贝构造或拷贝赋值,此时可以重写它们并将权限设置为private,但这样只是利用语法特性来碰巧实现效果,且对友元会带来困惑。可以使用关键字 =delete 标记不想被类实例调用的拷贝构造和拷贝赋值,相当于删除了它们。

代码示例:

#include <iostream>

/*
在C++的类中,有四类特殊的成员函数:
1.默认构造函数;2.拷贝构造函数;3.拷贝赋值函数(operator=);4.析构函数;
它们控制着类的实例的创建、初始化、拷贝以及销毁。
关键字 =default 和 =delete 在这四类特殊成员函数中的应用:
*/

/*
默认构造函数:如果对构造函数进行了重载,则编译器不会隐式的生成一个默认的构造函数,
此时如果调用了默认构造函数会在编译时报错,为了避免这种情况,一般会选择重写默认构造函数,且函数体为空。
关键字 =default 优化了这种行为,用该关键字标记重写的默认构造函数,编译器会隐式生成一个版本,
在代码更加简洁的同时,编译器隐式生成的版本的执行效率更高。
*/
class exemple1
{
public:
    // 重写构造函数  此时不会默认生成构造函数
    exemple1(int num) {}

    // 键字 =default 标记编译器隐式生成该类的默认构造函数,
    // 代码更简洁,且隐式生成的版本执行效率更高 
    exemple1() = default;
};

/*
拷贝构造函数 和 拷贝赋值函数:不论有没有对它们进行重载,编译器始终会隐式生成默认版本,
但有的时候不希望类实例进行拷贝构造或拷贝赋值,此时可以重写它们并将权限设置为private,
但这样只是利用语法特性来碰巧实现效果,且对友元会带来困惑。
可以使用关键字 =delete 标记不想被类实例调用的拷贝构造和拷贝赋值,相当于删除了它们:
*/
class exemple2
{
public:
    exemple2() = default;
    exemple2(exemple2& ob) = delete;
    exemple2& operator=(exemple2& ob) = delete;
};

int main()
{
    // 调用默认构造函数
    exemple1 e11;
    // 调用自定义构造函数
    exemple1 e12(1);

    exemple2 e21;
    // 编译错误 调用的拷贝构造函数已删除
    // exemple2 e22(e21);
    // 编译错误 调用的拷贝赋值函数已删除
    // exemple2 e23 = e21;

    return 0;
}

三、using关键字

在C++11中 using还可以用来定义别名(alias),例如:
using ll = long long;
有了这行代码 在后续就可以用ll 代替 long long类型

代码示例:

#include <iostream>

/*
在C++11中 using还可以用来定义别名(alias),例如:
using ll = long long;
有了这行代码 在后续就可以用ll 代替 long long类型
*/
using ll = long long;

int main()
{
    ll res = 0;
    std::cout << "size of res = " << sizeof(res) << std::endl;

    return 0;
}

运行结果:

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值