C++ const 关键字用法总结
概述
const是constant的缩写,本意是不变的,不易改变的意思。在C++中是用来修饰内置类型变量,自定义对象,成员函数,返回值,函数参数。
C++ const允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程的过程中有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。
const关键字的作用
1.const关键字定义常量
static const sf::Uint32 DICE = 'DICE';
static const sf::Uint32 PLANE = 'PLNE';
static const sf::Uint32 CDICE = 'CDIC';
static const sf::Uint32 CPLANE = 'CPLE';
static const sf::Uint32 HELLO = 'HELO';
static const sf::Uint32 FULL = 'FULL';
static const sf::Uint32 EXIT = 'EXIT';
static const sf::Uint32 START = 'STRT';
static const sf::Uint32 CSTART = 'CSTR';
static const sf::Uint32 SETNUMBER = 'SNUM';
static const sf::Uint32 SETNAME = 'SNAM';
static const sf::Uint32 CHAT = 'CHAT';
static const sf::Uint32 CCHAT = 'CCHA';
static const sf::Uint32 JOIN = 'JOIN';
static const sf::Uint32 STARTED = 'STED';
这是我在写CS模型联网飞行棋时定义的一系列常量,用于标识某些参数。
我们常见的还有一种定义常量的方式是
#define A 10
这种定义常量的作用方式是在代码的编译阶段,将代码文本中的“A”字符串替换成“10”字符串。
这种定义常量的方式在代码编写的阶段不能进行类型检查,而使用const定义常量,在定义常量的同时就可以保证后续使用该常量的时候有类型检查。
2.函数传参时的类型检查
void func(T a);
void func(const T& a);
对比上面两个函数,当我们希望在一个函数里面传入一个参数,又不希望修改这个参数的值的时候,我们可以在函数参数中将这个参数设置为const,这样如果我们在函数内执行
a=10;//ERROR
这样的代码的时候,编译器就会报错,因为const参数在函数内是不可改变的。
const参数还有一个好处。
当我们希望传入一个参数,但是我们不希望修改这个参数的,只是读取这个参数的数据的时候,我们可以传入一个普通的非引用的参数。但是传入参数时函数会在栈上复制一份这个参数,会造成一定的资源损耗。
这时我们可以传入一个const引用参数,传入引用参数时函数就不会再消耗资源复制一份数据,而是直接引用传入参数的地址,而const关键字又保证我们传入的引用不会被修改,就在减少资源损耗的情况下保证了引用的安全。
3.修饰指针
const int* a=10;//指针所指向的变量,也就是*a的值不可变,但是a有可能指向其他的变量
int* const a=10;//指针a不可变,也就是a永远指向*a,但是*a可以变
const int* const a=10;//指针a和指针指向的变量*a都不可变
const修饰指针的时候,如果const关键字在 * 的左边,那么指针所指向的变量不可变。
如果const关键字在 * 的右边,那么指针永远指向他初始化的那个地址。
4.修饰函数返回值
const修饰函数返回值的例子用的不多,其本质和修饰指针一样,因为我们的函数名也就是一个指针,和变量不同的是,我们的函数指针指向的是一个函数,指针指向的是一个变量
const int func();
//相当于const int* p=func();
const int* func();//把func()看成一个变量,则func()的内容不会变
//相当于int* const p=func();
int* const func();//吧func看成一个指针,则这个指针不会变
5.在类内使用const
#include<iostream>
using namespace std;
class A
{
public:
A(int _a):a(_a)
const int a;
int b;
int c;
void func1()
{
cout<<a;
}
void func2() const
{
a++;//error
func1();//error
cout<<b<<endl;
}
void func3() const
{
cout<<c<<endl;
}
void func4() const
{
func3();
}
} ;
const修饰类的成员函数的时候,const成员函数不能对该类的成员变量进行修改,否则报错,如func2()中的a++。
同时,在const修饰的成员函数中,只能调用同样被const修饰的成员变量,否则也会报错,如func2()中调用不是const成员函数的func1();
还有就是类中的const成员变量不能在定义的时候初始化
class A
{
public:
const int a=0;//报错
}
我们需要在构造函数中对其进行初始化
class A
{
public:
A(int _a):a(_a){}
const int a;
}