6

考虑以下代码。

#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++ 如何决定调用哪个方法?

4

4 回答 4

10
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 限定。[示例:对于 class 的 const 成员函数,X假定额外参数具有“对 const 的引用X”类型。]

因此,如果对象是const编译器,则编译器将选择具有隐式对象参数类型的成员函数版本引用 constObject,即 const 的 const 版本Print()

于 2012-09-13T04:24:36.337 回答
3

所有函数重载的工作方式相同。

在考虑重载成员函数时,它包括隐式this参数。如果函数已声明const,则this参数为const Object *。如果函数不是const,则this参数是Object *。由于const限定符影响函数重载规则,这意味着const函数的性质也会影响函数重载规则。

在您的具体示例中,print_obj(obj1)printconst因为print_obj()被声明为采用 a const Object&,这意味着它将始终const调用Print(). 与print_obj(obj2).

obj1.Print()打印mutable因为obj1is not const,因此非const版本 ofPrint()是一个更好的匹配并且被挑选用于函数重载决议。

obj2.Print()打印const因为obj2is const,因此const版本 ofPrint()是唯一合适的函数重载。

pobj1->Print()打印mutable因为*pboj1是一个非const值,所以选择非const版本Print()的函数重载决议。

最简单的思考方式是,如果你只是拥有

void Print(Object &obj);
void Print(const Object &obj);
于 2012-09-13T04:25:39.957 回答
1

请记住,对于普通对象,如果非const版本可用,则const选择非版本;否则const选择版本。下面是分析:

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
于 2012-09-13T04:29:12.677 回答
-2

如果两者都可以,它会更喜欢 const 方法而不是非常量方法。

同样适用于易失性,顺便说一句。

于 2012-09-13T04:24:04.783 回答