我有函数重载的问题。我将通过一些简单的示例向您展示:
class A {};
class B : public A{};
void somefunction(A&, A&);
void somefunction(B&, B&);
void someotherfunction() {
...
A& a1 = ...
A& a2 = ...
...
}
a1 和 a2 都是 B 的实例但是
somefunction(a1,a2);
通话
void somefunction(A&, A&);
我做错了什么?我的意思是多态性和重载就是为了类似的东西,不是吗?
编辑:好的,现在我知道它不起作用(感谢您的回答)。
任何解决方案如何做到这一点?无需类型转换。
edit2:好的,保留原样,使用类型转换,因为我想要的东西是不可能的。感谢大家的帮助。
最佳答案
静态转换它们以便编译器知道选择哪一个:
void somefunction((B&)a1, (B&)a2);
您遇到此问题的原因是程序设计,而不是语言。编译器根据传入的类型选择使用哪个函数。C# 将以完全相同的方式运行(很确定 Java 也会如此)。
在我看来,您在错误的地方实现了多态性。 somefunction
确实属于类 a
并且应该是虚拟的。然后,无论何时在运行时调用 a
的实例,都会调用正确类中的覆盖。
所以,实际上它应该是这样的:
class a {
public:
virtual somefunction(a& a2) {
//do stuff
}
}
class b : public a {
virtual somefunction(a& a2) {
b& b2 = (b&)a2;
//do stuff
}
}
class c : public b {
virtual somefunction(a& a2) {
c& c2 = (c&)a2;
//do stuff
}
}
上述解决方案在虚函数内部使用了最少的强制转换,并假定两个实例的类型相同。这意味着 b.somefunction(a())
将具有未定义的行为。
更好的解决方案是依赖C++ RTTI并使用 dynamic_cast,如果无法进行向下转换,它将返回 NULL。
此问题称为 double dispatch problem并且在维基百科文章中的描述与您描述的差不多。此外,维基百科为 multiple dispatch 提供的唯一解决方案是使用dynamic_cast
。
编辑 好的,这一直困扰着我,这里是一个基类和两个子类之间完全双重分派(dispatch)的解决方案。它并不漂亮,并且使用了一些 C++ 技巧,如友元类(实际上是为了更好的封装,而不是相反)和前向声明。
class b;
class c;
class a {
protected:
virtual void somefunction(a& a2); //do stuff here
virtual void somefunction(b& b2); //delegate to b
virtual void somefunction(c& c2); //delegate to c
public:
virtual void doFunc(a& a2) {
a2.somefunction(*this);
}
friend class b;
friend class c;
};
class b : public a {
protected:
virtual void somefunction(a& a2); //do stuff here
virtual void somefunction(b& b2); //do stuff here
virtual void somefunction(c& c2); //delegate to c
public:
virtual void doFunc(a& a2) {
a2.somefunction(*this);
}
friend class a;
};
class c : public b {
protected:
virtual void somefunction(a& a2); //do stuff here
virtual void somefunction(b& b2); //do stuff here
virtual void somefunction(c& c2); //delegate to c
public:
virtual void doFunc(a& a2) {
a2.somefunction(*this);
}
friend class a;
friend class b;
};
//class a
void a::somefunction(a& a2) {
printf("Doing a<->a");
}
void a::somefunction(b& b2) {
b2.somefunction(*this);
}
void a::somefunction(c& c2) {
c2.somefunction(*this);
}
//class b
void b::somefunction(a& a2) {
printf("Doing b<->a");
}
void b::somefunction(b& b2) {
printf("Doing b<->b");
}
void b::somefunction(c& c2) {
c2.somefunction(*this);
}
//class c
void c::somefunction(a& a2) {
printf("Doing c<->a");
}
void c::somefunction(b& b2) {
printf("Doing c<->b");
}
void c::somefunction(c& c2) {
printf("Doing c<->c");
}
关于c++函数重载问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2159496/