使用子类型重载调用函数

Call function using subtype overload

考虑以下程序

class A {};

class B : public A {};

void fun(A v) { std::cout << "A" << std::endl; }

void fun(B v) { std::cout << "B" << std::endl; }

void call(A v) { fun(v); }

int main(int argc, char *argv[]) {
   A a;
   B b;

   call(a);
   call(b);
   fun(a);
   fun(b);
}

它将打印

A
A
A
B

有没有办法让程序在第二种情况下注意到变量实际上是一个B,因此调用重载的fun(B),这样输出就会变成下面这样?

A
B
A
B

您有什么理由不希望 fun 成为 class 的一部分吗?如果 fun 是 class 上的 virtual 方法,调用采用 A 并简单地执行 v.fun() 它会找到正确的实现来执行

选项 1

您可以为 call 函数使用模板。

#include <iostream>

class A {};

class B : public A {};

void fun(A v) { std::cout << "A" << std::endl; }

void fun(B v) { std::cout << "B" << std::endl; }

template <typename T>
void call(T v) { fun(v); }

int main(int argc, char *argv[]) {
   A a;
   B b;

   call(a);
   call(b);
   fun(a);
   fun(b);
}

仅当 fun 的重载采用 T 类型的参数时才会编译,在您的情况下为 AB

Working example

选项 2

或者,您可以将这些自由函数变成 virtual class 方法并实际使用多态性。

#include <iostream>

class A
{
public:
    virtual void fun() { std::cout << "A" << std::endl; }
    void call() { fun(); }
};

class B : public A
{
public:
    virtual void fun() override { std::cout << "B" << std::endl; }
};

int main(int argc, char *argv[]) {
   A a;
   B b;

   a.call();
   b.call();
   a.fun();
   b.fun();
}

Working example