Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;基于派生类的重载方法_C++_Overloading_Derived Class - Fatal编程技术网

C++ C++;基于派生类的重载方法

C++ C++;基于派生类的重载方法,c++,overloading,derived-class,C++,Overloading,Derived Class,我的代码面临以下问题: #include <iostream> using namespace std; class Base { public: virtual void sayHello()=0; }; class Impl1 : public Base { public: void sayHello() { cout << "Hi from Impl1" << endl; } }; class Impl2 : public Bas

我的代码面临以下问题:

#include <iostream>

using namespace std;

class Base {
public:
    virtual void sayHello()=0;
};

class Impl1 : public Base {
public:
    void sayHello() { cout << "Hi from Impl1" << endl; }
};

class Impl2 : public Base {
public:
    void sayHello() { cout << "Hi from Impl2" << endl; }
};

void sayHello(Impl1 *i) {
    cout << "Impl1 says: ";
    i->sayHello();
}

void sayHello(Impl2 *i) {
    cout << "Impl2 says: ";
    i->sayHello();
}

int main()
{
    Impl1 *i1 = new Impl1();
    Base *b = i1;

    sayHello(b);

    return 0;
}
#包括
使用名称空间std;
阶级基础{
公众:
虚拟void sayHello()=0;
};
第1类:公共基础{
公众:

void sayHello(){cout重载解析在编译时执行。这意味着for
sayHello(b);
,编译器只知道
b
的类型是
Base*
,它不会也不可能知道
b
实际上指向
Impl1
对象。然后导致调用不明确;将
Base*
转换为
Impl1*
Impl2*
是调用的等效秩

PS:可能是OT,但对于您的代码示例,使用
Base*
的函数可以正常工作;动态dispach将生效

class Base {
public:
    virtual void sayHello()=0;
};

class Impl1 : public Base {
public:
    void sayHello() { cout << "Hi from Impl1" << endl; }
};

class Impl2 : public Base {
public:
    void sayHello() { cout << "Hi from Impl2" << endl; }
};

void sayHello(Base *i) {
    cout << "Some derived class of Base says: ";
    i->sayHello();
}

int main()
{
    Impl1 i1;
    Impl2 i2;

    Base *b = &i1;
    sayHello(b);   // "Hi from Impl1"
    b = &i2;
    sayHello(b);   // "Hi from Impl2"

    return 0;
}

由于重载是在编译时解析的,因此必须向编译器提供确切的类型,才能成功解析重载

要在类型上分派,请将虚拟成员函数添加到
,并使用它选择重载:

class Base {
public:
    virtual void sayHello()=0;
    virtual void callSayHello() = 0;
};

class Impl1 : public Base {
public:
    void sayHello() { cout << "Hi from Impl1" << endl; }
    void callSayHello() {sayHello(this); }
};

class Impl2 : public Base {
public:
    void sayHello() { cout << "Hi from Impl2" << endl; }
    void callSayHello() {sayHello(this); }
};

void sayHello(Impl1 *i) {
    cout << "Impl1 says: ";
    i->sayHello();
}

void sayHello(Impl2 *i) {
    cout << "Impl2 says: ";
    i->sayHello();
}
...
b->callSayHello();
类基{
公众:
虚拟void sayHello()=0;
虚拟void callSayHello()=0;
};
第1类:公共基础{
公众:

void sayHello(){cout去掉两个独立函数,直接调用
b->sayHello();

Impl1 *i1 = new Impl1();
Base *b = i1;
b->sayHello();
或者在
动态\u cast
中使用难看的解决方法:

Impl1 *i1 = new Impl1();
Base *b = i1;
sayHello(dynamic_cast<Impl1*>(b));
Impl1*i1=newimpl1();
基*b=i1;
sayHello(dynamic_cast(b));;
求助于
dynamic_cast
的需要通常表明类设计中存在错误。这里很可能就是这种情况。很有可能你根本就不应该引入所谓的面向对象基类



还要注意的是,您没有在最后调用
delete
。如果调用,则需要在
Base

中使用虚拟析构函数。您没有将
Base*
作为参数的sayHello函数。我基本上希望将我的对象传递给一个函数,该函数根据对象的类型执行一些计算。我的对象是故意的缺少进行所需计算所需的信息。@ZdravkoDonev:我添加了一个替代解决方案。是的,我想到了
if
-
else if
和dynamic\u cast,但这似乎不是一个好主意。关于引入基类的问题,也许你是对的。但是在我的代码的某些部分,我需要处理我的实现离子作为一个基类,在另一个基类中,我需要区分它们。那么我如何在运行时进行此对话呢?我基本上是想将我的对象传递给一个函数,该函数根据对象的类型进行一些计算。我的对象故意缺少信息,以便进行所需的计算。@ZdravkoDonev所以您需要知道实际情况。@ZdravkoDonevl函数内部的派生类型?您可能需要
dynamic_cast
。因此您建议:if(dynamic_cast(b)){}else if(dynamic_cast(b)){}else{//“谁知道”类型}解决方案?@ZdravkoDonev您可以这样做,但这不是一个好主意。我的答案中显示的第一个代码示例会更好;不要依赖于实际的派生类型,而是依赖于接口(即
Base
class).是的,但是我的派生类不包含进行计算所需的数据,我不想传递不同类的对象,因为我将得到一个意大利面代码。在这种情况下,我应该怎么做?
Impl1 *i1 = new Impl1();
Base *b = i1;
sayHello(dynamic_cast<Impl1*>(b));