函数重载的c ++问题

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:好吧保持原样,使用类型转换,因为我想要的东西是不可能的.感谢你的帮助.

Igo*_*aka 9

静态地抛出它们,以便编译器知道要选择哪一个:

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)