c++函数重载问题

标签 c++ polymorphism overloading

我有函数重载的问题。我将通过一些简单的示例向您展示:

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/

相关文章:

C++ 传递函数作为具有多态类型的参数

scala - Spark/Scala、数据集和案例类的多态性

c++ - 返回bitset的成员函数,继承自基类

mysql进程不断重载

c++ - 模板类并将数组初始化为零

c++ - 如何从 systeminfo.exe 显示的区域设置字符串中检索 "Human Readable"字符串?

c++ - 在 CLion 中找不到 gzip_decompressor(cpp boost 库)

c++ - 如果需要超过 5 秒,如何退出使用 C++ 运行的进程?

c++ - 模板和重载

c++ - 如何使用 result_of 代替 decltype?