在类层次结构中重载

以下示例将使用此类层次结构:

struct A { int m; };
struct B : A {};
struct C : B {};

从派生类类型到基类类型的转换优先于用户定义的转换。当通过值或通过引用传递时,以及将指向派生的指针转换为指向基础时,这适用。

struct Unrelated {
    Unrelated(B b);
};
void f(A a);
void f(Unrelated u);
B b;
f(b); // calls f(A)

从派生类到基类的指针转换也比转换为 void*更好。

void f(A* p);
void f(void* p);
B b;
f(&b); // calls f(A*)

如果在同一继承链中存在多个重载,则首选派生的基类重载最多。这基于与虚拟调度类似的原则:选择最专业的实现。但是,重载决策始终在编译时发生,并且永远不会隐式地向下转换。

void f(const A& a);
void f(const B& b);
C c;
f(c); // calls f(const B&)
B b;
A& r = b;
f(r); // calls f(const A&); the f(const B&) overload is not viable

对于指向与类相反的成员的指针,类似的规则适用于相反的方向:最少派生的派生类是优选的。

void f(int B::*p);
void f(int C::*p);
int A::*p = &A::m;
f(p); // calls f(int B::*)