Geo*_*rge 3 c++ polymorphism overloading
我有功能重载的问题.我将向您展示一些简单的例子:
class A {};
class B : public A{};
void somefunction(A&, A&);
void somefunction(B&, B&);
void someotherfunction() {
...
A& a1 = ...
A& a2 = ...
...
}
Run Code Online (Sandbox Code Playgroud)
a1和a2都是B的实例
somefunction(a1,a2);
Run Code Online (Sandbox Code Playgroud)
电话
void somefunction(A&, A&);
Run Code Online (Sandbox Code Playgroud)
我做错了什么?我的意思是多态性和重载是这样的东西,不是吗?
编辑:好的,现在我知道它不起作用(感谢您的答案).
任何解决方案如何做到这一点?没有铸造.
edit2:好吧保持原样,使用类型转换,因为我想要的东西是不可能的.感谢你的帮助.
静态地抛出它们,以便编译器知道要选择哪一个:
void somefunction((B&)a1, (B&)a2);
Run Code Online (Sandbox Code Playgroud)
你遇到这个问题的原因是程序设计,而不是语言.编译器根据传入的类型选择使用哪个函数.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
}
}
Run Code Online (Sandbox Code Playgroud)
上面的解决方案在虚函数内部使用最小的转换,并假设两个相同类型的实例.这意味着b.somefunction(a())将有未定义的行为.
更好的解决方案是依赖C++ RTTI并使用dynamic_cast,如果无法进行向下转换,则返回NULL.
这个问题被称为双调度问题,并且在维基百科文章中对其进行了描述.此外,维基百科为多次发送提供的唯一解决方案是使用dynamic_cast.
编辑好了,这一直困扰着我,这里是基类和两个子类之间完全双重调度的解决方案.它不是很漂亮,并且使用了一些像朋友类一样的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");
}
Run Code Online (Sandbox Code Playgroud)