C++类中,const的用法个人总结主要有以下几种:
1. 用来修饰成员变量,比如const int var;
2. 用来修饰形参,主要针对引用,比如const type&
3. 用来修饰返回值,返回常量引用;
4.放在成员函数的形参列表的“)”之后,大括号“}”之前;
#include
#include
using namespace std;
class Person
{
public:
//构造函数
Person() = default;
Person(const string& name, const string& id, unsigned age) :
m_name(name), m_age(age), m_id(id) { }
//公有的接口
const string& name() const { return m_name; }
const string& id() const {return m_id; }
unsigned age() const { return m_age; }
void set_name(const string& name) { m_name = name; }
private:
//C++支持类内初始值
string m_name = "";
const string m_id = ""; //常量数据成员
unsigned m_age = 0;
};
比如定义了上面的Person类,对4种用法分别进行总结:
1. const用来修饰成员变量
用const修饰的成员变量,必须在构造函数的初始化列表中对const修饰的成员进行初始化,比如Person类,在初始化列表中对m_id成员进行了初始化,如果在构造函数体内,不叫初始化,那叫赋值,m_id已经使用了类内初始值初始化了,再对它进行赋值的话,编译报错!
Person(const string& name, const string& id, unsigned age) :
m_name(name), m_age(age), m_id(id) { } //正确,在初始化列表对const成员m_id进行初始化
Person(const string& name, const string& id, unsigned age) : m_name(name), m_age(age)
{
//错误!不能在构造函数体内对const成员赋值
m_id = id; //这是赋值,不是初始化,m_id已经初始化了,对已经初始化了的const对象赋值,编译报错
}
2. const修饰的形参
const修饰的形参主要针对引用或指针,比如对于类中的成员函数set_name(const string& name)
void set_name(const string& name) { m_name = name; }
//将形参声明为const,是为了使得函数的调用更有弹性,使得使用常量或者非常量都可以调用
int main()
{
Person p; //调用默认构造函数实例化一个Person的对象p
const string name1("Megatron"); //const string对象name
string name2("Galvatron"); //普通的string对象
p.set_name(name1); //正确!常量引用绑定到常量对象上,如果形参不使用const修饰,无法调用
p.set_name(name2); //正确,常量引用可以绑定到非常量对象上
}
3. 放在成员函数的形参列表的“)”之后,大括号“}”之前
个人理解:这种情况下const修饰的是this指针所指向的对象*this,就是调用成员函数的对象本身!这里的const就是为了限制成员函数无法对this指向的对象进行修改,此时*this对象是只读的。
(1)编译器也提供检查,一旦检查到成员函数对this指向的对象进行了修改,就报错!
(2)如果在小括号“)”和大括号“{”之间没有使用const,且函数内部没有对*this进行修改,有的情况下会编译出错,比如:
const string& name()
{
//小括号和大括号之间没有const
//函数体内没有没有对this对象修改
return m_name;
}
Person p1("megatron", "xxx-xx-xx-001", 1000);
p1.name() //可以,编译通过!
const Person p2("Galvatron", "xxx-xx-xx-001", 1000);
p2.name() //编译报错!
4. 返回常量引用
如果在小括号“)”和大括号"{"之间加了const,且函数返回类型为引用,则必须返回const引用,返回普通引用编译报错!比如:
string& name() const { return m_name; }
//右边的const是用来修饰*this的,说明不可以对*this进行修改
//如果左边不加const,只是返回普通的引用,由于引用可以作为左值,可以对其进行赋值,比如
Person p("megatron", "xxx-xx-xx-001", 1000);
p.name() = "Galvatron"; //这样就相当于修改了*this,而右边的const限制了不能对*this进行更改