C++系列-const所有用法总结
const用法总结
- const修饰变量
- const修饰普通变量
- const修饰指针变量
- 常量指针
- 指针常量
- 常量指针常量
- const修饰引用
- const修饰函数形参
- 参数是普通的值传递
- 参数类型是引用
- const修饰函数返回值
- 值传递方式返回
- 指针方式返回
- 常量引用方式返回
- const修饰成员函数
- 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