C++中const关键字修饰

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010853261/article/details/84929652

C++中const使用的地方非常多,修饰包括:全局变量、函数、函数参数等等,这篇文章主要是总结一下const各种使用的规则以及需要注意事项。

const名叫常量限定符,用来限定特定变量,以通知编译器该变量是不可修改的。习惯性的使用const,可以避免在函数中对某些不应修改的变量造成可能的改动。

C++中const的主要用法大致上可以分为以下几类:

  • 修饰基本数据类型
  • 应用到函数中
  • 在类中用法
  • const修饰类对象,定义常量对象

1.const修饰基本数据类型

主要是修饰值变量、reference、pointer

1.1修饰一般常量或则数组

比如:

const int a = 10;
const int arr[3]={1,2,3}; 

对于类似这些基本数据类型,修饰符const可以用在类型说明符前,也可以用在类型说明符后,其结果是一样的。在使用这些常量的时候,只要不改变这些常量的值便好。

1.2const修饰指针变量*及引用变量&

const修饰指针(*)

这里有一些实际的示例:

int x= 100;
const int* a1 = &x;//[1]
int const * a2 = &x;//[2]
int* const a3 = &x;//[3]
const int* const a = &x;//[4]

《Effective c++》Item21上的总结非常直观明了。

  • 如果const位于星号*的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
  • 如果const位于星号*的右侧,const就是修饰指针本身,即指针本身是常量。

根据这条规律,[1]和[2]两条中,const位于星号的左侧,所以const含义是修饰变量a1和a2指针指向的内容是常量,也就是不能做 *a1 = 1或则 *a12 = 1这种类似操作,编译器会报错。

[3]为指针本身是常量,而指针所指向的内容不是常量,这种情况下不能对指针本身进行更改操作,如a++是错误的.

[4]为指针本身和指向的内容均为常量。

const修饰reference(&)
同样给出一些示例:

int x =100;
int const &a=x;//[1]
const int &a=x;//[2]
int &const a=x;//[3]这种方式定义是C、C++编译器未定义,虽然不会报错,但是该句效果和int &a一样。   

对于[1]和[2]这两种定义方式是等价的,此时的引用a的值不能被更新。如:a++ 或则给a赋值这是错误的。

2.const应用到函数中

const在函数中的应用主要有三点:

  • 作为参数的const修饰符;
  • 作为函数返回值的const修饰符
  • 作为函数的const修饰符

不管是作为函数参数的const修饰符还是返回值的修饰符,其实际含义都是一样的。

const修饰函数参数

比如:void fun0(const A* a ); 或则 void fun1(const A& a);
调用函数的时候用相应的变量初始化const常量,则在函数体中,按照const修饰的部分进行常量化。

比如const A* a 则不能对传递进来的指针指向的内容修改,保护原指针所指向的内容;
比如const A& a则不能对传递进来的引用对象的内容修改,保护原引用对象所的内容。

注意:参数const通常用于参数为指针或引用的情况。

const修饰函数返回值

修饰返回值的const,如const A fun2( ); const A* fun3( );
这样声明了返回值后,const按照"修饰原则"进行修饰,保护函数返回的指针指向的内容或则引用的对象不被修改。

const修饰函数
const作用于函数还有一种情况是,在函数定义的最后面加上const修饰,比如:
A fun4() const;
其意义上是不能修改除了函数局部变量以外的所在类的任何变量。

3. 类中定义常量(const特殊用法)

我们要想在类中实现常量定义大致上有几种实现方式

1.使用枚举类型

class test
{
	enum {SIZE1=10, SIZE2=20};//枚举常量
	int array1[SIZE1];
	int array2[SIZE2];
}

2.使用const

不能在类声明中完成初始化const数据成员。 以下用法编译器会报错,因为类对象未被创建时,编译器不知道SIZE的值是什么。

// 错误实例
class test
{
	const int SIZE = 100;//编译器报错,企图在类声明中初始化const数据成员
	int array[SIZE];//错误,未知SIZE
}

正确使用const用法是:const数据成员的初始化只能在类构造函数的初始化表中进行。

class A
{
	A(int size);//构造函数
	const int SIZE;
};
A::A(int size) : SIZE(size) // 构造函数的初始化表
{

}
//error 赋值的方式是不行的
A::A(int size)
{
     SIZE=size;
}
void main()
{
    A  a(100); // 对象 a 的SIZE值为100
    A  b(200); // 对象 b 的SIZE值为200
}

注意:对const成员变量的初始化,不能在变量声明的地方,必须在类的构造函数的初始化列表中完成,即使是在构造函数内部赋值也是不行的。

3.使用static const

通过结合静态变量来实现:

class Year
{
private:
	int y; 
public:
	static int const Inity;
public: 
	Year()
	{
		y=Inity;
	}
};
int const Year::Inity=1997;//静态变量的赋值方法,注意必须放在类外定义
void main()
{
	cout<<Year.Inity<<endl;//注意调用方式,这里是用类名调用的。
}

到这里就把在类中定义常量的方法都陈列出来了。

4.const定义常量对象,以及常量对象的用法

对于不管是标准库中的对象或则是我们自定义的对象,如果我们定义的是const对象,那么对于const对象只能调用const修饰的函数,其余的函数都不能调用。

如下例子:

class test
{
public:
    test():x(1)
    {
        y=2;
    }
    ~test()
    {}
    void set(int yy)
    {
        y=yy;
    }
    int getx() const
    {
        return x;
    }
    const int x;
    int y;
};

void main()
{
	const test t;// 定义的一个const对象
	t.set(33);//error,set方法不是const修饰的方法,编译器会报错。
	t.getx();
}

猜你喜欢

转载自blog.csdn.net/u010853261/article/details/84929652