C++ const及constexpr关键字

最近复习了一下关于const和constexpr的用法,在这里总结一下。错漏之处,请不吝指正。

const关键字

c中的const

1.变量定义

const int a = 10;

使用这种方式定义的变量,它的值不会改变,在其整个作用域中固定。这也就是说,const变量只会被初始化一次(可以使用变量或函数的返回值来初始化const变量)。
值得一提的是,const变量可以用来初始化数组,这也就说明了,const类型定义的数据,编译器是将其作为常量处理的。

2.const与指针

const int* p_1;
int const* p_2;
int* const p_3;

const int* const p_4;
int const* const p_5;

const配合指针的使用通常有以上几种场景。通常我们认为前两种情况是相同的,都是限制指针指向位置的变量不可变,而指针的指向是可变的;第三种情况表示,指针的指向是不可变的,而指针指向位置的变量是可变的。
最后两种情况是以上两种用法的结合,不难想象,其代表的含义就是指针指向位置的变量不可变,同时指针的指向也是不可变的。

3. 修饰函数形参

size_t strlen ( const char * str );
int strcmp ( const char * str1, const char * str2 );
char * strcat ( char * destination, const char * source );
char * strcpy ( char * destination, const char * source );
int system (const char* command);
int puts ( const char * str );
int printf ( const char * format, ... );

引用部分标准库中的函数定义,可以看到,很多使用const关键字对形参做出限制。其作用与修饰变量类似,表示某个形参不能被修改,或是某个形参指针指向不能被修改。目的是为了提高函数的健壮性。同时也告诉程序员,使用本函数不会对传入的某些参数做出修改。

4. 修饰函数返回值

const char * FUN(void);

使用这种方式,声明的函数,表示函数返回的指针不能被修改。同时,改返回值的接收指针也必须是const修饰的指针,否则会报错。

c++中的const

主要是static在类中的使用。在类中修饰变量与类外修饰变量的使用方式类似,此处不再赘述。主要介绍使用const修饰类成员函数的用法。

1.const修饰类成员函数

class Stack {
public:
	void push(int const& item);	
	void pop();					
	int top() const;			
	bool empty() const;

private:
	vector<int> elems;
};

const 修饰类成员函数,其目的是防止成员函数修改被调用对象的值,如果我们不想修改一个调用对象的值,所有的成员函数都应当声明为 const 成员函数
注意:const 关键字不能与 static关键字同时使用,因为 static 关键字修饰静态成员函数,静态成员函数不含有this指针,即不能实例化,const成员函数必须具体到某一实例。

constexpr关键字

constexpr是c++11新添加的特征,目的是将运算尽量放在编译阶段,而不是运行阶段。这个从字面上也好理解,const是常量的意思,也就是后面不会发生改变,因此当然可以将计算的过程放在编译过程。constexpr可以修饰函数、结构体。

1.constexpr修饰变量

const int bb = 1;
constexpr int a = bb + 2;

定义变量时可以用 constexpr 修饰,从而使该变量获得在编译阶段即可计算出结果的能力。
使用 constexpr 修改普通变量时,变量必须经过初始化且初始值必须是一个常量表达式。

2.constexpr修饰函数

constexpr int sum(const int _x, const int _y)
{
    return _x + _y;
}

简单的来说,如果其传入的参数可以在编译时期计算出来,那么这个函数就会产生编译时期的值。但是,传入的参数如果不能在编译时期计算出来,那么constexpr修饰的函数就和普通函数一样了。不过,使用constexpr修饰函数是有一定要求限制的,如果函数体适用于constexpr函数的条件,可以尽量加上constexpr

使用constexpr 的限制

  • constexpr函数中只能调用其它constexpr函数
  • constexpr函数中只能使用全局constexpr变量
  • 函数中只能有一个return语句(但允许包含typedefs、 using declaration && directives、静态断言等)

3.constexpr修饰结构体

class Circle
{
public:
   constexpr Circle(double radius) :radius(radius) {}

   const double PI = 3.14;
   const double radius;
};

int main()
{
    constexpr Circle c = {4};
    cout << c.radius << endl;
    return 0;
}

可以看到,如上所示就可以使用constexpr修饰一个类的构造函数。值得注意的是,constexpr 修饰类的构造函数时,要求该构造函数的函数体必须为空,且采用初始化列表的方式为各个成员赋值时,必须使用常量表达式。
其实 constexpr 也可以修饰类中的成员函数,只不过此函数必须满足前面提到的 3 个条件。

4.constexpr修饰模板

constexpr 可以修饰模板函数,但由于模板中类型的不确定性,因此模板函数实例化后的函数是否符合常量表达式函数的要求也是不确定的。
针对这种情况下,C++11 标准规定,如果 constexpr 修饰的模板函数实例化结果不满足常量表达式函数的要求,则 constexpr 会被自动忽略,即该函数就等同于一个普通函数。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值