文章稍长,但是举例都很易懂。
1. 常量
c++用const将对象i定义为一个常量。定义之后,i的值就不可以再变了,所以i必须在定义时候被初始化。
所以 const int i; //错误的,i 必须被初始化 (在C中这种写法可以,但是这里只说C++的环境下)
#include<iostream>
int main()
{
const int i = 10; //正确,i被初始化
}
2. 代替#define的值替换功能
举例:
#define NUMBER 100
上面这行代码是C中典型的值替换手段。
但是C++中这样写:
const NUMBER = 100;
//或者
const int NUMBER = 100;
这样写的好处:
①.明显的减少代码量
②.const可以附带数据类型(int),但是#define(宏常量)没有该功能,只是简单的字符替换,没类型检查,所以在字符替换的时候会出意想不到的错误。
3.指针和const
在指针的声明中,指向const对象的指针和const指针是不一样的。
举例:
//注意!!p可以不初始化,它可以指向任何东西。p这个指针指向一个int类型的数,但是这个数是const属性。
const int* p;
//等价于
int const *p;
//下面的p是个const修饰的指针,所以p必须被初始化。 但是这个p指向的值可以被改变。
int a = 1;
int* const p = &a;
*p = 2; //改变p所指向的值,正确。
4.修饰函数参数及函数返回值
①const修饰成员函数
class A{
void fun1();
void fun2() const;
};
const改变的是this指针。this指针原类型为: A* const(this为类A的指针,我理解为A* const this),被const修饰后变为:const A* const,(第一个const修饰的就是this指向的对象,我理解为 const A* const this)。
const修饰的成员函数不能调用或者修改该类的对象。当然mutable成员可以。
再记最重要的一点:const修饰的成员函数的应用场景。
const对象,指向const对象的指针都且只能调用const成员函数。调用非const成员函数则会出错。反过来,非const对象或者指针,都可以调用const成员函数和非const成员函数。所以,如果一个类中没有const成员函数,当你使用const对象时,这个对象谁都调用不了。
举例:
class A {
void fun1() const;
void fun2();
}
const A a1; //a1对象只可以调用fun1成员函数。
const A* a2 = new A; //a2指针的调用规则也是只可以调用fun1函数。
class B {
void bfun1();
void bfun2();
}
B b1; //b1可以调用bfun1和bfun2
const B b2; //b2调用不了任何成员函数
B* b3 = b2; //b3是指向const对象b2的指针,也调用不了任何成员函数
B& b4 = b2; //b4是const修饰的b2对象的引用,也调用不了任何成员函数。
//总结:无论是const对象(b2),还是指向b2的指针b3,还是b2的引用b4,都无法调用非const成员函数。
class C {
void cfun1();
void cfun2() const;
}
C c;
c.cfun1(); //正确
c.cfun2(); //正确
//总结:非const修饰的对象,可以调用const成员函数和非const成员函数。
②const修饰数据成员
const修饰数据成员,记住一点:必须在构造中初始化成员变量。
#include<iostream>
class A{
public:
int m_a;
const int m_b;
}
A a; //此处想要构造一个对象a,但是程序不会执行。
//因为const修饰的成员变量m_b必须在构造的初始化列表中进行初始化
//修改如下:
class A{
public:
A()
: m_b(100)
{} //初始化时,初始化const修饰的成员变量,这样就可以了。
int m_a;
const int m_b;
}
待续…