C+ + 成员函数 cv-qualifier 重载

示例

当通过具有CV资格的对该类的引用来访问它们时,该类中的函数可能会过载。这是最常用的过载const,但可用于过载volatile和const volatile,太。这是因为所有非静态成员函数都将其this用作隐藏参数,cv限定词将应用于该隐藏参数。这是最常用于重载的方法const,但也可以用于volatile和const volatile。

这是必需的,因为只有在至少具有与调用它的实例相同的cv资格的情况下,才可以调用该成员函数。非const实例既可以调用成员也可以调用const非const成员,而const实例只能调用const成员。这允许函数根据调用实例的cv-qualifiers具有不同的行为,并允许程序员qualifier(s)通过不提供带有该函数的版本来禁止不需要的cv-的函数qualifier(s)。

具有某些基本print方法的类可能会const像这样重载:

#include <iostream>

class Integer
{
    public:
        Integer(int i_): i{i_}{}

        void print()
        {
            std::cout << "int: " << i << std::endl;
        }

        void print() const
        {
            std::cout << "const int: " << i << std::endl;
        }

    protected:
        int i;
};

int main()
{
    Integer i{5};
    const Integer &ic = i;
    
    i.print(); // prints "int: 5"
    ic.print(); // prints "const int: 5"
}

这是const正确性的关键原则:通过将成员函数标记为const,可以在const实例上调用它们,这又允许函数在const不需要修改实例的情况下将其作为指针/引用。这允许代码通过将未修改的参数作为const和没有cv限定词的修改后的参数来指定是否修改状态,从而使代码更安全,更易读。

class ConstCorrect 
{
  public:
    void good_func() const 
    {
        std::cout << "我不在乎实例是否为const。" << std::endl;
    }

    void bad_func() 
    {
        std::cout << "I can only be called on non-const, non-volatile instances." << std::endl;
    }
};

void i_change_no_state(const ConstCorrect& cc) 
{
    std::cout << "I can take either a const or a non-const ConstCorrect." << std::endl;
    cc.good_func(); //好。可以从const或非const实例中调用。
    cc.bad_func();  //错误。只能从非const实例调用。
}

void const_incorrect_func(ConstCorrect& cc) 
{
    cc.good_func(); //好。可以从const或非const实例中调用。
    cc.bad_func();  //好。只能从非const实例调用。
}

这种方法的常见用法是将存取const器声明为,将变体声明为non- const。


在const成员函数中不能修改任何类成员。如果确实需要修改某些成员,例如锁定a std::mutex,则可以将其声明为mutable:

class Integer
{
    public:
        Integer(int i_): i{i_}{}

        int get() const
        {
            std::lock_guard<std::mutex> lock{mut};
            return i;
        }

        void set(int i_)
        {
            std::lock_guard<std::mutex> lock{mut};
            i = i_;
        }

    protected:
        int i;
        mutable std::mutex mut;
};