C++常量和具有相同名称的可变函数
C++ const and mutable functions with the same name
考虑以下代码。
#include <iostream>
using namespace std;
class Object
{
public:
Object() {}
void Print() const
{
cout << "const" << endl;
}
void Print()
{
cout << "mutable" << endl;
}
};
void print_obj(const Object& obj)
{
obj.Print();
}
int main()
{
Object obj1;
const Object obj2;
Object*const pobj1 = &obj1;
print_obj(obj1);
print_obj(obj2);
obj1.Print();
obj2.Print();
pobj1->Print();
return 0;
}
输出为
const
const
mutable
const
mutable
我想知道,当面对许多同名的可变方法时,C++是如何决定调用哪个方法的?
print_obj(obj1);
print_obj(obj2);
要调用的函数是根据传递对象的cv限定符(const
/volatile
)进行评估的。请注意,函数重载解析时会考虑cv限定符
如果传递的对象是const
,则选择接收const
参数的函数。若传递的对象是非常量,则选择接收非常量参数的函数。
obj1.Print();
obj2.Print();
pobj1->Print();
如果对象是const
,则只能调用调用const
成员函数
如果对象是非常量,则非常量版本优先于const
版本。
这些规则由标准明确规定。
参考:
C++03标准:
§13.3.1候选函数和参数列表:
对于非静态成员函数,隐式对象参数的类型为"引用cv
X
",其中X
是函数所属的类,cv是成员函数声明上的cv限定。[示例:对于类X
的const成员函数,假定额外参数的类型为"reference to constX
"。]
因此,如果对象是const
,编译器将选择成员函数的版本,该成员函数具有类型为的隐式对象参数,引用常量Object
,这是Print()
的常量版本。
所有函数重载的工作方式相同。
当考虑重载成员函数时,它包括隐式this
参数。如果函数声明为const
,则this
参数为const Object *
。如果函数不是const
,则this
参数是Object *
。由于const
限定符会影响函数重载规则,这意味着函数的const
性也会影响函数过载规则。
在您的特定示例中,print_obj(obj1)
打印const
,因为print_obj()
被声明为采用const Object&
,这意味着它将始终调用Print()
的const
版本。print_obj(obj2)
也是如此。
obj1.Print()
打印mutable
,因为obj1
不是const
,因此Print()
的非const
版本是更好的匹配,并且是为函数过载分辨率而选择的。
obj2.Print()
打印const
,因为obj2
是const
,因此Print()
的const
版本是唯一合适的函数重载。
pobj1->Print()
打印mutable
,因为*pboj1
是非const
值,因此选择Print()
的非const
版本作为函数过载分辨率。
最简单的想法是,如果你只是有会发生什么
void Print(Object &obj);
void Print(const Object &obj);
请记住,对于普通对象,如果有非const
版本可用,则选择非const
版本;否则选择CCD_ 51版本。以下是分析:
print_obj(obj1); // print_obj() receives const argument, so `const` is chosen
print_obj(obj2); // same as above
obj1.Print(); // obj1 is not const, so non-const version is chosen
obj2.Print(); // obj2 is const, so must choose const version
pobj1->Print(); // pobj1 is a const pointer pointing to non-const object, so non-const version is chosen
如果两者都可以,那么它更喜欢const方法而不是非const方法。
同样适用于挥发性、BTW.
- 有没有什么方法可以使用一个函数中定义的常量变量,也可以由c++中同一程序中的其他函数使用
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- constexpr构造函数需要常量成员函数时出现问题
- std::函数常量正确性未遵循
- 具有常量引用参数的函数模板专用化
- constexpr 函数获取常量字符*
- 在定义的函数中使用常量时出错
- Clang 格式 10.0 与 5.0 常量成员函数的格式不同
- C++ 获取函数在常量引用中按值返回的结果
- 函数签名与调用的函数不匹配,常量字符[]和字符*之间的区别?
- 为什么下面带有非常量转换函数的代码没有歧义?
- 与 map 一起使用时复制构造函数常量错误
- 静态函数常量静态成员函数
- 如何在指向常量地址时声明成员函数常量指针
- C++getter函数:常量和非常量
- C++循环中调用伪随机数生成器函数 - 常量种子问题
- 提升::任何构造函数 - 常量类型重载分辨率
- 函数常量返回类型:类型引用的初始化无效
- C++模板通过指针的函数/常量指针的函数进行的部分专用化没有什么不同
- 虚函数常量与虚函数非常量