C++关键字-const与volatile限定说明符

     上一节讲到mutable时,使用了const限定符,本节主要是对cv限定符进行说明。const在平常经常使用,它可以被施加于任何作用于内的对象、函数参数、函数返回类型、成员函数本体等。另外限定符中还有一种:volatile,它是为了改善编译器的优化能力而设的。

  •      const:表示一个被修饰的对象不能被修改。使用它可以使得编译器强制实施这项约束。他可以修饰类之外的global或者namespace作用域的常量,也可以修饰static对象或者变量。在使用const需要注意地方主要有:

1.#define与const的区别与使用

在effictive c++中条款2和3都提到尽量使用const,在#define与const都可使用的情况下,推荐使用const。至于原因,自己感觉不是很清楚,从网上查阅了不少资料,对两者的区别总结如下:

#define TEST_RADIO 1.653
const double TestRadio =1.653;

(1)#define是宏定义语句,由预处理器处理,对编译器是透明的;const则是c++的关键字,被修饰变量即为常量,是由编译器处理的。

(2)#define定义的TEST_RADIO没有类型,同样没有类型检查;const定义的TestRadio则声明为double类型,在编译阶段会检查其类型。

(3)#define定义的TEST_RADIO是一个立即数,没有内存分配,在使用过程中则是每次使用就需要分配一次内存;const定义的TestRadio则是一次分配,以后使用过程中只是传递其内存地址,并不增加内存。

(4)#define不重视作用域,无法创建class专属变量,没有封装性;const则使用较为灵活,可以修饰class专属变量、指针、函数等,作用域与其声明的位置不同而变化。

2.const初始化

      const修饰的变量在不同地方声明,其初始化规则是不同的,尤其同static、extern结合使用的时候。具体初始化规则解释如下:

ConstTest.h

class ConstTest
{
public:
	ConstTest();
	~ConstTest();
public:

	double test2;			//只能在类内部初始化
	const double test3 ;		//必须在初始化列表中初始化,不能在构造函数初始化
	const static int test4 =4;	//只有静态整型常量可在声明时初始化或者在类外初始化,其他只能在类外初始化
	static double test5;		//必须在类外初始化
	static const double test8;	//同test4
};


ConstTest.cpp

#include "ConstTest.h"

double test0 = 0.01;			//一般要求在声明时初始化,亦可以不用。可在其他文件中使用
const double test1 = 0.11;		//必须在声明时初始化,默认链接性为内部(只能在本文件中使用)
extern const double test6 =0.66;	//声明时必须初始化,不然无法使用。提供外部链接性(可在其他文件中使用)
static const double test7 = 0.77;	//同test


const double ConstTest::test8 =0.88;    //类专属静态常量,初始化在类外,不必再写static关键在,但是必须写const关键字
double ConstTest::test5 = 0.55;		//类专属静态变量,初始化在类外

ConstTest::ConstTest():test3(0.33)	//类专属常量,必须在成员初始化列表中初始化
{	
	test2 = 0.22;			//类专属变量
}

ConstTest::~ConstTest()
{
}


main.cpp

#include <iostream>
#include "ConstTest.h"
extern double test0; 
//extern double test1;       //链接性为内部,无法使用
extern const double test6 ;
//extern double test7;       //链接性为内部,无法使用
using namespace std;
int main()
{
	ConstTest* test = new ConstTest;
	cout<<"extern修饰的全局变量test0="<<test0<<"\n";
	cout<<"test1是链接性为内部,且非类专属的常量,无法使用"<<"\n"; 
	cout<<"普通类专属非静态变量test2="<<test->test2<<"\n";
	cout<<"const修饰类专属非静态常量test3="<<test->test3<<"\n";
	cout<<"const、static修饰类专属静态常量test4="<<test->test4<<"\n";
	cout<<"static修饰类专属静态变量test5="<<test->test5<<"\n";
	cout<<"extern、const修饰的全局常量test6="<<test6<<"\n";
	cout<<"test7是链接性为内部,且非类专属的静态常量,无法使用"<<"\n";
	cout<<"static、const修饰类专属静态常量test8="<<test->test8<<"\n";
	system("pause");
	return 0;
}
以上的运行结果是:


3.const修饰指针,const在不同的位置是有不同的意义的。

int m_test = 1;  
int* p = &m_test;  //指针和指针指向的值都不是常量
const int* p = &m_test; //指针不是常量,可更改指向,指针指向的值是常量,不可以通过指针操作符修改
int* const p = &m_test; //指针是常量,不可以更改指向与加减,其指向的值不是常量,可以通过指针操作符修改
const int* const p = &m_test; //指针与指针指向的值都是常量,都不可修改
       注意:将const放在类型之后,星号*之前  和   const放在类型之前的的意义是一致的。


4. const修饰函数的返回值,尤其是一些重载操作符的函数;修饰函数形参;修饰类成员函数本身。

class Test{
...
const Test operator* (const Test& lhs, const Test& rhs); //修饰函数的形参,可以使得形参在函数中被修改。
void Show() const; //修饰成员函数,防止该成员函数修改调用的对象
};
Test a,b,c;
...
(a*b) = c; //可防止对函数的返回值进行在再赋值

  • volatile:主要用于改善编译器的优化能力。假设编译器发现,程序在几条语句中几次使用了某个变量值,则编译器可能不是让程序查找两次变量值,而是将这个变量值缓存到寄存器。这种优化假设变量的值在这几次使用之间不会变化。如果不将变量声明为volatile,则编译器将进行这种优化;将变量声明为volatile,相当于告诉编译器,不要进行这种优化。[引用C++ Primer Plus]

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值