目录
1.常对象
- 在声明时用const进行修饰的对象称为常对象 ,一旦创建,其数据成员在对象的整个生存期将不能再被修改
- 在声明常对象时必须初始化,且最好使用初始化列表进行初始化,以确保成员变量被正确初始化。如果不设定初始化列表而使用构造函数中的赋值语句对成员变量进行赋值,相当于试图改变一个已经被设定只读的变量,此时程序可能出现错误。
- 常对象只能调用常成员函数,调用普通的成员函数时编译器会报错
class A {
private:
int x;
public:
A(int a):x(a){}//初始化列表
void test1();//普通成员函数
void test2()const;//const修饰的常成员函数
};
void A::test1(){
this->x++;
}
void A::test2()const{
cout <<x;
}
int main(){
const A a(3);//const修饰的常对象
//a.test1()调用会报错
a.test2();//常对象可调用常成员函数
return 0;
}
使用常对象有以下好处:
- 防止意外修改
- 允许传递给只接受常量参数的函数
- 提高代码可读性,当一个对象被const修饰后,意味着对象值不能被修改,使代码简洁明了,减少出错机会
2.常成员函数
- 常成员函数在定义和声明时都必须使用const关键字修饰,且必须放在参数列表之后,函数之前
- 常成员函数承诺不会修改对象状态
- 如果以const为区分对成员函数进行重载时,常对象只能调用常成员函数,而非const修饰的对象可以调用两个版本的成员函数,这时编译器将选择最近的函数--非const修饰的成员函数,非const修饰的对象的常引用则调用常成员函数
class A {
private:
int x;
public:
A(int a):x(a){}//初始化列表
void test();//普通成员函数
void test()const;//const修饰的常成员函数
};
void A::test(){
cout << "调用非const修饰的test函数" << endl;
}
void A::test()const{
cout << "调用const修饰的test函数" << endl;
}
int main(){
const A a1(2);
a1.test();//调用const修饰的test函数
A a2(2);
a2.test();//调用非const修饰的test函数
const A& a3 = a2;
a3.test();//调用const修饰的test函数
return 0;
}
3.常数据成员
-
常数据成员指不能被修改的类数据成员,通过const修饰来实现
-
常数据成员必须使用初始化列表来进行初始化
-
常数据成员也可以是静态的,这时通过static const来修饰,且在类内声明,类外定义并初始化,类外定义时只需要用const修饰即可。但也可以类中定义并进行初始化,这时可以不再类外定义。总之,静态常数据成员必须进行初始化,否则会报错
class A {
private:
const int x;//
static const int y=10;//类内定义静态常数据成员并初始化
static const int z;//类内声明静态常数据成员,并在类外加以定义并初始化
public:
A(int a):x(a){}//初始化列表用来初始化常数据成员
void test()
{
cout << y << endl;
cout << z << endl;
cout << x << endl;
}
};
const int A::z=20;//类外加以定义静态常数据成员并初始化
int main(){
A a(3);//用初始化列表对常数据成员进行初始化
a.test();
return 0;
}
程序运行结果:
4.常指针
- 有两种类型:一是可以声明指向常量的指针, 另一种是声明指针类型的常量
指向常量的指针:
- 不可以通过指针来改变对象所指的值,但指针本身可以改变指向别的对象
- 语法为 const 指针类型 * 指针名 或 指针类型 const * 指针名
const int* p=&a;// 指向常量的指针
int const* p=&a//指向常量的指针
指针类型的常量:
- 指针本身的值不能改变,因此在定义时必须进行初始化操作,且不能改变指向别的对象,但可以改变所指对象的值
- 语法为 指针类型 * const 指针名
int* const p=&a;//定义指针常量指向a所在的内存空间(初始化)
p=&b;//报错,p2是指针常量,其值不能改变
*p=20;//改变a的值为20
5.常引用
- 在声明时用const修饰的引用就叫常引用 ,语法为 const 数据类型 &引用名
- 常引用可以防止代码修改引用的对象,一般作为函数的形参,提高代码的健壮性
- 非const的引用不能绑定常对象,但常引用既能绑定常对象,又能绑定普通对象,且绑定后只能把该对象当做常对象
常引用的定义方式:
const int &re=num;
常引用通常应用于做函数形参,避免不必要的拷贝的同时还能保证引用对象不被修改
void print(const string& str)
{
cout << "the string is " << str << endl;
}
int main()
{
string s = "hello!";
print(s);//the string is hello!
return 0;
}
常引用还可以作为返回值类型,不用进行复制操作,但返回的如果是局部对象必须用static保证生命周期
const string& test()
{
static string s = "hello world!";//必须用static保证生命周期
return s;
}
int main() {
string ss = test();
cout << ss;//hello world!
return 0;
}