关于类和结构体中的const

发布时间 2023-12-11 11:04:07作者: Wangtn

一个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’} asthis’ 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类型时,意味着成员变量不可修改,这种成员函数本身就是不能被调用的。