C++学习笔记(一):const的用法


前言

最近在复习C++的相关知识,之前的学习过于零碎,有很多知识有所遗漏,关于const的用法很多,在这里我想做一个总结,希望自己学习的同时也可以帮助到别人。

在c++中,一个const不必创建内存空间,是否为const常量分配内存空间依赖于如何使用。一般说来,如果一个const仅仅用来把一个名字用一个值代替(就像使用#define一样),那么该存储局空间就不必创建。如果存储空间没有分配内存的话,在进行完数据类型检查后,为了代码更加有效,值也许会折叠到代码中。下面介绍几种const在C++中的常见用法。


一、定义常量

const定义的常量通常有以下两个基本性质。

1.定义完之后不可修改

const int a = 10;
a = 5;   /错误!! a为常量不可修改

2.定义时必须初始化

const int a ; //错误!!定义时必须初始化

对于基础数据类型,编译器不会为其分配内存,而是放到一个符号表中。
那么什么时候会为其分配内存呢?可以分为以下几种情况。

1.extern给const变量分配内存

const修饰的全局变量默认是内部链接,即只在当前源文件有效 不能直接用于其他源文件,如果必须用在其他源文件 使用只读的全局变量 必须加extern将变量转换成外部链接。此时,对常量分配内存地址。

const int a = 10;   //默认内部链接,文件内访问
extern const int a; //转化为外部链接,其他源文件可以访问

2.取地址会分配临时内存

如果程序中获取了const变量的地址,例如通过指针或引用,编译器可能会为该const变量分配内存,以便在取地址的地方存储该变量的值。但是,不能通过指针修改常量的值。

const int a = 5;
const int *p = &a; //定义指向常量的指针
*p = 10;  //错误!不能通过指针修改常量的值

3.变量初始化分配内存

当用变量给const变量赋值时,系统直接为其开辟空间 而不会把它放入符号表中。

int a = 10;
const int b = a;

二、指针与const

这部分在写代码时比较常用,有时候很容易记混。const与指针通常有三种不同的写法。

1.指向常量的指针

表示指针指向的值是常量,不能通过该指针修改所指向的值。本质上一个常量,指针用来说明常量的类型,表示该常量是一个指针类型的常量。在指针常量中,指针自身的值是一个常量,不可改变,始终指向同一个地址。在定义的同时必须初始化。

const int *ptr;//两种不同的写法
int const *ptr;//p is a pointer to const char

int a = 10; // 声明一个整数变量并初始化为10
int const* p = &a; // 声明一个指向常量整数的指针,指向整数变量a的地址
*p = 20; // 错误,不能通过p来修改所指向的整数值
int value = *p; // 合法,读取指针p所指向的整数值,value将等于10

int a = 20;// 可以修改指针p本身的值
p = &a; // 合法,将指针p指向新的整数变量a的地址

2.常量指针

常量指针本质上是一个指针,常量表示指针指向的内容,说明该指针指向一个“常量”。常量指针不能指向其他变量,但所指向的值可以修改。

int* const ptr = 10 ; //错误!只能指向变量的地址
int* const ptr;   //错误!必须进行初始化,即指针必须指向一个已存在的变量。

int a = 10;
int* const ptr = &a;  //正确!p is a const pointer to char
a = 5;				//可以修改所指向的值
cout<<*p<<endl;		//输出为5

3.指向常量的常量指针

表示指针本身是常量,不能指向其他变量,并且指针指向的值也是常量,不能通过该指针修改所指向的值。

const int a= 10; // 声明一个常量整数并初始化为10
const int* const ptr = &a; // 声明一个指向常量整数的常量指针,指向常量整数a的地址
int value = *ptr; // 合法,读取指针ptr所指向的常量整数值,value将等于10

总结:这里有一个简单的判断方法:如果关键字const出现在星号左边,表示被指物是常量;如果出现在星号右边,表示指针自身是常量;如果出现在星号两边,表示被指物和指针两者都是常量。

三、函数中的const

const最具有威力的用法是面对函数声明时的应用。在一个函数声明式内,const可以和函数返回值,各参数,函数自身产生关联。接下来挨个介绍他们的用法。

1.修饰函数参数

在函数的参数列表中使用const关键字,可以指定某些参数为常量,即在函数内部不能修改这些参数的值。
这样做有两个主要目的:一是表明函数不会修改这些参数的值,增加函数的安全性和可读性;二是允许函数接受常量参数,从而可以传递常量或非常量对象给函数。

void func(const int var); // 传递过来的参数不可变
void func(int *const var); // 指针本身不可变
}

参数为引用,为了增加效率同时防止修改。
对于非内部数据类型的参数而言,像void func(A a) 这样声明的函数注定效率比较低。因为函数体内将产生A 类型的临时对象用于复制参数a,而临时对象的构造、复制、析构过程都将消耗时间。为了提高效率,可以将函数声明改为void func(A &a),因为“引用传递”仅借用一下参数的别名而已,不需要产生临时对象。`

void function(A &a);
void function(const A &a);

2.修饰函数返回值

2.1函数返回const指针

函数返回类型声明为 const int* 。表示函数返回的是一个指向常量整数的指针,即指针指向的值是常量,不能通过该指针修改所指向的值。
返回const指针通常用于提供只读的访问方式,避免对指向的数据进行修改。

const int* getConstPointer() {
    static int value = 100;
    return &value; // 返回指向常量整数的指针
}

2.2函数返回const引用

函数返回类型声明为 const int& 。表示函数返回的是一个常量引用,即在函数外部不能通过该引用修改引用所绑定的对象的值。
返回const引用通常用于提供只读的访问方式,避免对引用所绑定的对象进行修改。

const int& getConstReference() {
    static int value = 100;
    return value; // 返回常量引用
}

四、类中的const

1.const修饰成员函数

类的成员函数后面加 const。 void fun() const {}表明这个函数不会对这个类对象的数据成员(准确地说是非静态数据成员)作任何改变。在设计类的时候,一个原则就是对于不改变数据成员的成员函数都要在后面加 const,而对于改变数据成员的成员函数不能加 const。

class Person
{
public:
	Person()
	{
		this->m_Age = 0;
		this->m_ID = 0;
	}

	void func()const {
		this->m_Age = 10; //加上mutable关键字,可以修改
		this->m_ID = 20;  //m_ID不可修改,会报错
	}

private:
	mutable int m_Age;
	int m_ID;

};

2.const修饰对象

我们只需要在类对象实例化时前面添加const即可。对于const修饰的对象,只需要记住一句话:非const类对象既可以访问const成员函数也可以访问非const成员函数,const类对象只能访问const成员函数。

class Person
{
public:
	Person()
	{
		this->m_Age = 0;
		this->m_ID = 0;
	}

	void func()const {
		//this->m_Age = 10; //m_ID不可修改,会报错
		this->m_ID = 20;  //加上mutable关键字,可以修改
	}
	void Show() {
		this->m_Age = 1000;
		cout << "ID:" << this->m_ID << " Age:" << this->m_Age << endl;
	}
public:
	int m_Age;
	mutable int m_ID;

};



int main() 
{	
	
	const Person p1;
	cout << "Age:" << p1.m_Age << endl;
	cout << "ID:" << p1.m_ID << endl; //可读

	//p1.m_Age = 30;    //不可修改
	p1.m_ID = 40; //可以修改mutable修饰的成员变量

	p1.func();//只能访问const修饰的函数
	//p1.Show()   不能访问
	system("pause");
	return EXIT_SUCCESS;
}

总结

本文介绍了const在C++编程中常见的情况,通过总结可以了解const的大部分用法,但是想要熟练运用,还应该在实践编程中不断提高。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值