c++相同的方法签名,但不同的返回类型
C++ identical method signature but different return type
我看到了以下代码:
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让我注意到描述中的初始混淆。
相关文章:
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- C++方法是否可以根据传递给构造函数的参数具有不同的返回类型?
- 具有引用返回类型的重写方法上的协变返回类型无效
- Java 调用 dll 字符串返回类型方法
- 必须使用尾随返回类型的示例,因为无法用旧方法解决问题
- 如何拥有两个名称相同但返回类型不同的纯虚拟方法
- qml 未知方法返回类型:ArchiveFile*,即使调用了 qmlRegisterUncreatableType
- std::d eclval vs crtp,无法从不完整类型推断方法返回类型
- 将返回类型推断为模板参数类型方法
- dlsym() 解决方法返回类型
- 我如何根据某些模板参数影响模板类方法的返回类型
- 访问方法的返回类型
- 更改基类方法在其派生类中的返回类型
- 具有协变返回类型的方法在 VC++ 上崩溃
- 如何检查模板类方法返回类型
- 如何使用类型专用化模板方法,该类型本身就是一个模板,其中只有返回类型依赖于模板类型
- 解释C 中三种返回类型的方法
- 覆盖方法返回类型,在C 中使用不完整的派生类
- 存储方法的返回类型和参数类型
- C 多重继承,虚拟方法覆盖问题和协变量返回类型