c++相同的方法签名,但不同的返回类型

C++ identical method signature but different return type

本文关键字:返回类型 方法 c++      更新时间:2023-10-16

我看到了以下代码:

template <class T>
class Type {
    public:
        Type() {}
        T& operator=(const T& rhs) {value() = rhs; return value();}
        T& value() {return m_value;}
        T value() const {return m_value;}
    private:
        T m_value;
};

为什么编译器没有报错

    T& value() {return m_value;}
    T value() const {return m_value;}

和如何知道哪一个被调用?

这两个函数实际上并不相同。只有第二个函数被声明为const成员函数。如果调用成员的对象是const,则使用后一种选项。如果对象为非const,则使用第一个选项。

的例子:

void any_func(const Type *t)
{
    something = t->value(); //second `const` version used
}
void any_func2(Type *t)
{
    something = t->value(); //first non-`const` version used
}

如果两个函数都声明为非const,或者都声明为const,编译器(无论如何都应该)报错。

为什么编译器没有报错

因为const计数不同的函数签名。你假设函数签名是相同的是错误的。标记为const的函数将被任何const实例或Type<T>的引用调用。

和如何知道哪一个被调用?

cout语句放入函数中,并测试以下情况:

template <class T>
class Type {
    public:
        Type() {}
        T& operator=(const T& rhs) {value() = rhs; return value();}
        T& value() { 
            std::cout << "non const version" << std endl;
            return m_value;
        }
        T value() const { 
            std::cout << "const version" << std endl;
            return m_value;
        }
    private:
        T m_value;
};

int main() {
    Type<int> t;
    t.value();
    Type<int> rt = t;
    rt.value();
    Type<int>* pt = &t;
    pt->value();
    const Type<int> ct;
    ct.value();
    const Type<int>& crt = t;
    crt.value();
    const Type<int>* pct = &t;
    pct->value();
}

赋值操作符将调用非const版本。


const版本最好看起来像

const T& value() const { 
     std::cout << "const version" << std endl;
     return m_value;
}

,因为您不能总是依赖RVO(返回值优化),并且可能需要额外的副本(特别是对于较旧的编译器实现)。


还要注意赋值操作符应该返回对当前实例的引用:

 Type& operator=(const T& rhs) {value() = rhs; return *this;}

关于函数解析优先级的几句话。编译器通过以下方式区分const/非const函数:

如果一个类只有带有给定名称和参数列表的const函数,它将被常量和非常量对象调用。调用此函数后,对象将"假定"为const(即使它不是const),这意味着该函数只能调用其他const函数。

如果一个类只有非const函数,它将被非const对象调用。尝试为const对象调用此函数将导致编译错误。

如果一个类同时具有两个函数,则const版本将用于const对象,非const版本将用于非const对象。

感谢@owacoder让我注意到描述中的初始混淆。