C++高级使用技巧:const & constexpr

1 const 

1.1 const的作用

        const主要有两个作用:只读限制(一般用来声明函数参数)和常量限制(用于不可变恒值声明),主要区别在于是否具有确定数值

        const修饰指针变量时,可以放在type*之前或之后,const type* var 表示var所指向的值*var是不可变的, type* const var表示指针变量var是不可变的,即var不能重新指向其他变量。

void fun1(const int num) {

    int arr[num];    //ERROR,num只读性参数不用用作常量,只在函数调用时才能确定具体值

    const int num1 = 10;
    int arr1[num1];    //OK, 具有确定值的常量可以直接使用

    int val = 100;
    int val1 = 1000;
    const int* p1 = &val;
    *p1 = 200;    //ERROR, *p1是常量不能再修改
    p1 = &val1;    //OK,p1可以重指向

    int* const p2 = &val;
    *p2 = 200;    //OK,p2指向值可以改变
    p2 = &val1;    //ERROR, p2不能重指向
        
}

1.2 const 和 #define的区别     

        #define是预处理命令,它所定义的字符串在C++中称为宏定义const是一个关键字(keyword),用于使标识符(identifier)的值为常量。

        (1)编译时的处理方式不同:

        #define作用原理本质上就是预处理阶段在宏调用处进行字符替换处理不做任何计算

        const声明的常量具有变量属性,在编译时和运行时使用。

        (2)类型和安全检查不同

        #define宏定义的字符串所代表的变量或函数,在预处理阶段不做任何类型安全检查;

        const常量是有类型的,在编译阶段必须进行类型安全检查。

        (3)存储方式不同

        #define宏定义的变量是不分配内存的

        const定义的常量本质上仍然是变量,是需要分配内存的。

        但是,const常量在使用或运行时时可以节省空间,避免不必要的内存分配

        (4)define宏可以定义函数,此时函数相当于c++中的内联函数,而const只能定义常量

2 constexpr

        所谓常量表达式,指的是由多个常量组成且编译过程中就能直接获取计算结果的表达式。常量表达式的计算在编译阶段,这极大提高程序的执行效率,因为表达式只需要在编译阶段计算一次,节省了每次程序运行时都需要计算一次的时间。

2.1 constexpr修饰变量

        在 C++11 中新增了 constexpr 关键字,以用来修饰常量表达式,但是在定义常量时,const 和 constexpr 是等价的,都可以在程序的编译阶段计算出结果。C++ 内置类型的数据可以直接用 constexpr 修饰,自定义类型( struct / class )的数据也能直接用 constexpr 修饰。在constexpr声明中如果定义了一个指针,限定符conxtexpr仅对指针有效,与指针所指的对象无关

struct Car
{
    float price;
    const char* name;
};

void fun_test() {

    const int var_const = 1234;    //常量表达式 YES
    constexpr int var_constexpr = 1234;    //常量表达式 YES


    printf("var_const: %d\n", var_const);    
    printf("var_constexpr: %d\n", var_constexpr);


    constexpr Car car{15000.0, "geely"};    //常量表达式 YES
    car.price = 10000.0;    //ERROR,不能修改常量

    const int*p = nullptr;        //p是一个指向整形常量的指针
    constexpr int* q = nullptr;   //q是一个指向整数的常量指针
}

2.2 constexpr修饰函数

        constexpr修饰一般函数构成常量表达函数的条件有:函数的返回值必须是常量表达式;函数必须事先定义;在函数体中,除了using 指令、typedef 语句、 static_assert 断言、return 语句之外,不能出现非常量表达式之外的语句。

constexpr int fun_test_constexpr()
{
    constexpr int a = 100;
    constexpr int b = 10;
    return a + b;
}

2.3 constexpr类构造函数

使用 constexpr 修饰一个类的构造函数可以用来生成常量对象,常量构造函数有一个要求:构造函数的函数体必须为空,并且必须采用初始化列表的方式为各个成员赋值

class Student {
public:
    constexpr Student(const char* p, int age) :name_(p), age_(age)
    {
    }
private:
    const char* name_;
    int age_;
};
 
int main()
{
    constexpr struct Person p1("Ella", 39);
    cout << "luffy's name: " << p1.name_ << ", age: " << p1.age_ << endl;
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

弘毅—至善

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值