使用子类型重载调用函数

Call function using subtype overload

本文关键字:调用 函数 重载 类型      更新时间:2023-10-16

考虑以下程序

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

选项 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

工作示例

选项 2

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

#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();
}

工作示例

你有什么

理由不希望fun成为这些课程的一部分吗? 如果fun是类上的virtual方法,并且调用需要A并且简单地执行v.fun()它会找到要执行的正确实现