[TOC]
#1. Const values
1.1 Const修饰变量
const关键字修饰的变量为常量,编译器会阻止它被修改。被const修饰的变量必须初始化。
int main()
{
const int value1 = 5; // Copy initialization
const int value2(7); // Direct initialization
const int value3{ 9 }; // Uniform initialization(C++11)
value1 = 10; // C3892
value1++; // C2105
}
在C++中,可以通过const关键字来定义常量而不是通过#define预处理器伪指令来定义。被const修饰的变量可以用作常量表达式。
// compile with: /c
const int maxarray = 255;
char store_char[maxarray]; // allowed in C++; not allowed in C
1.2 Const修饰指针
const可以用于修饰指针变量. const修饰指针变量有两种情况,一种是修饰指针所指向的变量;另一种是修饰指针本身。
Const Pointer
Const Point(常量指针),指向常量的指针。意味着指针所指向的是常量,它指向的内容不能发生改变。但是指针本身是可以变化的。
声明
Type const * pvar_name;
const Type * pvar_name;
示例
int main()
{
int a = 1, b = 2;
const int *pi = &a;
printf("A=%d", *pi);
*pa = 10; // C3892,指针指向常量不能被修改
pi = &b; // 指针变量本身被修改
printf("B=%d", *pi);
system("pause");
}
Pointer Const
Pointer Const(指针常量),指针本身就是常量。意味着指针里面所存储的内容(内存地址)是常量,不能改变。但是,内存地址所对应的内容是可以通过指针改变的。
声明
Type * const pvar_name;
示例
int main()
{
int a = 1, b = 2;
int * const pi = &a;
*pi = 10; // 指针所指向的变量可以被修改
printf("A=%d", *pi);
pi = &b; // C3892,指针变量本身不能被修改
}
#2. Const class objects and member functions
2.1 Const classes
一旦被const修饰的类对象初始化完成,任何尝试对类的非const成员和方法进行访问都是不允许的。
class Date {
public:
Date(int yr, int mn, int dy) :year(yr), month(mn), day(dy) {};
int GetMonth();
void SetMonth(int mn);
private:
int year;
int day;
int month;
};
int Date::GetMonth() {
return month;
}
void Date::SetMonth(int mn) {
month = mn;
}
int main()
{
const Date date{ 2022,03,03 };
date.SetMonth(4); // C2662
auto month = date.GetMonth(); // C2662
}
2.2 Const member functions
被const修饰的类对象,只能访问类的const成员变量和成员函数。被const修饰的成员函数能确保其不会修改调用它的对象,并且也只能访问同为const的成员函数。为了声明一个函数为const成员函数只需要在其参数列表后面,函数体之前加上const关键字。
class Date {
public:
Date(int yr, int mn, int dy) :year(yr), month(mn), day(dy) {};
int GetMonth() const; // A read-only function,note addtion of const keyword after parameter list but before function body.
void SetMonth(int mn); // A write function;can't be const.
private:
int year;
int day;
int month;
};
int Date::GetMonth() const {
return month;
}
void Date::SetMonth(int mn) {
month = mn;
}
int main()
{
Date curDate{ 2022,05,27 };
const Date birthDate{ 2022,03,03 };
curDate.SetMonth(4);
auto birMn = birthDate.GetMonth(); // Const member function access by const class object.
std::cout << birMn << std::endl;
birthDate.SetMonth(10); // C2662, non-const member function cannot be called by const object.
auto curMn = curDate.GetMonth(); // const member function access by non-const class object.
std::cout << curMn << std::endl;
}
被const修饰的的成员函数,意味着隐藏的this指针*this所获取的也是const对象。意味着函数体内能访问的任何成员都是const的。const成员函数只能返回const成员引用。
被const修饰的成员函数可以被任意的对象(const或者non-const class object)调用,const对象或者non-const对象,但是non-const函数只能被non-const对象调用。
2.3 Overloading const and non-const function
同一函数可以通过添加const实现函数重载。
class Date {
public:
Date(int yr, int mn, int dy) :year(yr), month(mn), day(dy) {};
int GetMonth() const; // GetMonth for const class objects(return const reference)
int GetMonth(); // GetMonth for non-const class objects(return non-const reference)
void SetMonth(int mn);
private:
int year;
int day;
int month;
};
int Date::GetMonth() const {
return month;
}
int Date::GetMonth() {
return month;
}
void Date::SetMonth(int mn) {
month = mn;
}
网友评论