使用子类型重载调用函数
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
类型的参数时才会编译,在您的情况下为 A
或 B
。
选项 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();
}
考虑以下程序
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
类型的参数时才会编译,在您的情况下为 A
或 B
。
选项 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();
}