关于类和结构体中的const
一个const类型的类是无法调用非const类型的成员函数的,因此stl容器中类的成员函数都会有const的重载版本,因为不清楚用户会初始化const的类实例还是非const的类实例。
如下就是一个非法代码
#include <iostream> struct DataType{ int _m_public; DataType(int _m_pub, int _m_pri) : _m_public(_m_pub), _m_private(_m_pri){ std::cout << "ctor" << std::endl; }; void add_mprivate(){ ++_m_private; } void show_mprivate(){ std::cout << "_m_private: " << this->_m_private << std::endl; } private: int _m_private; }; using DT = struct DataType; int main(){ const DT data(1, 1); std::cout << "====== init\n"; std::cout << data._m_public << "\n"; data.show_mprivate(); }
我定义了一个const类型的结构体,因为它是const类型的,所以他不能访问非const类型的成员函数。因为const的类或结构体意味着整个类内的成员变量是不可修改的,而调用非const的成员函数有可能会造成成员变量的修改,所以在编译器看来这是不合法的,就会有如下错误
test.cc: In function ‘int main()’: test.cc:25:24: error: passing ‘const DT’ {aka ‘const DataType’} as ‘this’ argument discards qualifiers [-fpermissive] data.show_mprivate(); ^ test.cc:11:10: note: in call to ‘void DataType::show_mprivate()’ void show_mprivate(){ ^~~~~~~~~~~~~
因此,我需要再重载一份const的成员函数(对于show_mprivate这种不改变成员变量的成员函数是可以的)
#include <iostream> struct DataType{ int _m_public; DataType(int _m_pub, int _m_pri) : _m_public(_m_pub), _m_private(_m_pri){ std::cout << "ctor" << std::endl; }; void add_mprivate(){ ++_m_private; } void show_mprivate(){ std::cout << "_m_private: " << this->_m_private << std::endl; } void show_mprivate() const { std::cout << "_m_private: " << this->_m_private << std::endl; } private: int _m_private; }; using DT = struct DataType; int main(){ const DT data(1, 1); std::cout << "====== init\n"; std::cout << data._m_public << "\n"; data.show_mprivate(); }
但是对于add_mprivate函数,我们不能重载一份他的const版本,因为这个函数一定会修改成员变量,所以当class或者struce定义为const类型时,意味着成员变量不可修改,这种成员函数本身就是不能被调用的。
无情的摸鱼机器