C++系列-const所有用法总结


春日 - 朱熹
胜日寻芳泗水滨,无边光景一时新。
等闲识得东风面,万紫千红总是春。


const 是 constant 的缩写,本意是不变的,不易改变的意思。

const修饰变量

const修饰普通变量

  • 定义常量
  • 一般常量变量名用大写
#include <iostream>
using namespace std;
const int MAX_VALUE = 100;

void main()
{
	// MAX_VALUE = 50;		// 常量的值不可被修改,定义时就确定好了
	system("pause");
}

const修饰指针变量

常量指针

  • const int *p; const:常量 , * 指针,故为常量指针
  • const修饰的是*p,所以,*p不能修改,即指针指向的内容不能通过指针修改。 *p=xx 是错误的,但是指针本身可以修改,即指针可以指向其它地址。 p = &a 是正确的。
code:
#include <iostream>
using namespace std;
int main()
{
	int a = 10;
	int b = 20;
	const int* p = &a;
	cout << "a的地址: " << &a << endl;
	cout << "p的值: " << p << endl;
	// *p = 20;		// 错误,const修饰的是*p,则*p的值不可修改,即p指向的内容不可改
	p = &b;			// p的指向是可以修改的
	cout << "b的地址: " << &b << endl;
	cout << "p的值: " << p << endl;
	system("pause");
	return 0;
}

result:
a的地址: 00000001930FF5C4
p的值: 00000001930FF5C4
b的地址: 00000001930FF5E4
p的值: 00000001930FF5E4

指针常量

  • int * const p; * 指针, const 常量,故为指针常量
  • const修饰的是p,所以p不能修改,即指针的指向不能修改,不能指向其它的地址,但是指针指向的地址中的内容是可以通过*p=xx修改的。
code:
#include <iostream>
using namespace std;
int main()
{
	int a = 10;
	int b = 20;
	int* const p = &a;	// 指针常量,const修饰p,则p的指向不可修改
	cout << "a的地址: " << &a << endl;
	cout << "p的值: " << p << endl;
	// p = &b;		// 错误,p的指向不可修改
	*p = 20;		// ,const修饰的是*p,则*p的值不可修改,即p指向的内容不可改
	//p = &b;			// p的指向是不可以修改的
	cout << "a的值: " <<  a << endl;
	system("pause");
	return 0;
}

result:
a的地址: 000000AB945FF994
p的值: 000000AB945FF994
a的值: 20

常量指针常量

  • const int * const p:const 修饰了*,const又修饰了p,所以指针本身和其指向的内容都是常量,都不能修改。*p=xx错误,p=xx错误。

const修饰引用

  • 常量引用只是对引用可参与的操作做出了限定,对于引用的对象本身是不是常量未作限定,所以对象本身还是可以修改的。
code:
#include<iostream>
using namespace std;

int main(void)
{
	int i = 1;
	const int& cj = i;  // const引用普通变量
	cout << "------ 1 ------, " << cj << endl;
	//cj=2;				// 错误cj被const修饰,不可以改变,无法通过引用改变它引用的内容
	i = 3;				// 正确,i可以被修改,cj也随之被更改
	cout << "------ 2 ------, " << cj << endl;
	system("pause");
	return 0;
}

result:
------ 1 ------, 1
------ 2 ------, 3

const修饰函数形参

  • 形参的值在函数中是可以改变的,如果形参是个指针或者引用,则形参在改变时,直接改变的就是实参。
  • 防止参数在函数中被意外修改时,可以在形参前加const。
  • 写函数的时候尽量使用常量引用,不会产生副本,且可读性强。
  • 当函数的参数作为输出时,不应该const修饰,要不然你没法修改。

参数是普通的值传递

  • 普通的值传递,形参即使改变,也不会影响实参的结果,所以加不加const都无所谓。
code:
#include <iostream>  
#include <string>  
using namespace std;
void print_str(const string s)		// 值传递,形参和实参并不是同一空间,
// 这里加不加const都不会影响实参的值
{
	//s = "jh"; // 会报错,s无法修改
	cout << s << endl;
}
int main()
{
	string str1 = "hello world";
	print_str(str1);
	system("pause");
	return 0;
}

result:
hello world

参数类型是引用

  • 形参和实参指向的是同一空间,则限值了形参为const,形参无法改变,从而实参也不会改变。
#include<iostream>
using namespace std;

void func(const int &a)		// 在调用函数的时候,t1传给a,则a为t1的引用,而const修饰了a,那么a是无法改变的,t1也就无法改变
{
	cout << a << endl;
	//++a;  //是错误的,a 不能被改变
}

int main(void)
{
	int t1 = 10;
	func(t1);
	system("pause");
	return 0;
}

const修饰函数返回值

const修饰函数返回值,表示返回值不可被改变。

值传递方式返回

  • 如果函数返回值采用值传递方式,返即返回的是一个副本。修改这个副本并不会影响原始值,加不加const都一样。
// 以下效果一样
const int func1(int a);
int func1(int a);

指针方式返回

如果给以“指针传递”方式的函数返回值加 const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加 const 修饰的同类型指针;

const char * GetString(void); // 返回值是常量指针

//如下语句将出现编译错误:
//char *str = GetString();

//正确的用法是
const char *str = GetString(); // 返回是常量指针,则只能赋值给常量指针


常量引用方式返回

用 const 修饰返回的引用,保护引用的内容不被修改。

code:
#include <iostream>
using namespace std;

class Person {
public:
	int& get_age() 
	{
		cout << "m_age的地址: " << & m_age << endl;
		return m_age;
	}
	const int& get_age_const()	// const int &,则无法通过返回的引用改变m_age的值
	{
		return m_age;
	}
	void show_age() 
	{
		cout << "age: " << m_age << endl;
	}
private:
	int m_age = 0;
};

int main()
{
	Person p1;
	p1.show_age();
	cout << "p1.get_age()的地址: " << &p1.get_age() << endl;
	p1.get_age() = 5;	// p1.get_age()的返回值是m_age的引用,
	//这句话就是改变m_age的值,会修改成员变量的值
	p1.show_age();

	//p1.get_age_const() = 8;	// 编译器会报错,因为p1.get_age_const()返回的是
	// const int&, 常量引用,无法通过引用改变变量的值。
	//p1.show_age();
	system("pause");
	return 0;
}

result:
age: 0
m_age的地址: 0000002D1F3BF734
p1.get_age()的地址: 0000002D1F3BF734
m_age的地址: 0000002D1F3BF734
age: 5

const修饰成员函数

  • 成员函数后加const,称为常函数。
  • 常函数内不可以修改成员属性。
  • 成员属性在声明时,如果前面加mutable,在常函数仍然可以修改。

const 修饰在函数名后面

  • 其本质是const修饰的是this指针,this指针的本质是指针常量,即指针的指向(其地址)不可修改,在函数后加const后,是让this指针指向的内容也不可修改。
code:
	#include <iostream>
	using namespace std;
	class Horse
	{
	public:
		int age = 3;
		mutable string color = "white";
		//this 指针是一个指针常量, Horse * const this, 它指向的地址不可以修改, const Horse * const this, 则表示其空间的内容也不能修改
		void show_age() const		//常函数,const其实是用来修饰this指针的,表示this指向的内存空间的内容也不可以修改
		{
			//age = 5;				// 常函数中不能修改普通成员变量
			color = "black";		// 当成员变量被mutable修饰后,常函数中可以修改
			cout << "it is " << age << endl;
		}
	};
	
	int main()
	{
		Horse horse1;
		horse1.show_age();
		system("pause");
		return 0;
	}
result:
	it is 3

常对象

  • 在声明对象前加const,常对象,常对象的内容不可以修改。
  • 常对象只能调用常函数。
  • 常对象可以修改mutable修饰的成员变量。
code:
	#include <iostream>
	using namespace std;
	class Horse
	{
	public:
		int age = 3;
		mutable string color = "white";
		//this 指针是一个指针常量, Horse * const this, 它指向的地址不可以修改, const Horse * const this, 则表示其空间的内容也不能修改
		void show_info() const		//常函数,const其实是用来修饰this指针的,表示this指向的内存空间的内容也不可以修改
		{
			//age = 5;				// 常函数中不能修改普通成员变量
			color = "black";		// 当成员变量被mutable修饰后,常函数中可以修改
			cout << "it is " << age << endl;
		}
		void show_info_1()
		{
			//age = 5;				
			color = "black";
			cout << "it is " << age << endl;
		}
	};
	
	int main()
	{
		Horse horse1;
		horse1.show_info();
		const Horse horse2;			// 常对象内的内容不可以修改
		//horse2.age = 5;			// 常对象不能修改普通的成员变量
		horse2.color = "brown";		// 常对象可以修改mutable修饰的成员变量
		cout << horse2.age << endl;
		cout << horse2.color << endl;
		horse2.show_info();
		//horse2.show_info_1();		// 常对象不能调用普通的成员函数,因为普通成员函数可以修改成员变量的值,而常对象对应的成员变量是不可以修改的,冲突。
		system("pause");
		return 0;
	}
result:
	it is 3
	3
	brown
	it is 3
  • 13
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值