C++;:派生的+;基类实现单个接口? 在C++中,有可能有一个BASE PLUS派生类实现一个接口吗?

C++;:派生的+;基类实现单个接口? 在C++中,有可能有一个BASE PLUS派生类实现一个接口吗?,c++,class,inheritance,interface,C++,Class,Inheritance,Interface,例如: class Interface { public: virtual void BaseFunction() = 0; virtual void DerivedFunction() = 0; }; class Base { public: virtual void BaseFunction(){} }; class Derived : public Base, public Interface { public:

例如:

class Interface
{
    public:
        virtual void BaseFunction() = 0;
        virtual void DerivedFunction() = 0;
};

class Base
{
    public:
        virtual void BaseFunction(){}
};

class Derived : public Base, public Interface
{
    public: 
        void DerivedFunction(){}
};

void main()
{
    Derived derived;
}
此操作失败,因为无法实例化派生的。就编译器而言,从未定义Interface::BaseFunction

到目前为止,我找到的唯一解决方案是在派生类中声明一个传递函数

class Derived : public Base, public Interface
{
    public: 
        void DerivedFunction(){}
        void BaseFunction(){ Base::BaseFunction(); }
};
有没有更好的解决办法


编辑:如果有必要的话,这里是我在使用MFC对话框时遇到的一个现实问题


我有一个从CDialog派生的对话框类(比如说MyDialog)。由于依赖性问题,我需要创建一个抽象接口(MyDialogInterface)。使用MyDialogInterface的类需要使用MyDialog特定的方法,但也需要调用CDialog::SetParent。我刚刚通过创建MyDialog::SetParent并将其传递给CDDialog::SetParent解决了这个问题,但我想知道是否有更好的方法。

C++没有注意到从Base继承的函数已经实现了
BaseFunction
:该函数必须在从
接口
派生的类中显式实现。更改为:

class Interface
{
    public:
        virtual void BaseFunction() = 0;
        virtual void DerivedFunction() = 0;
};

class Base : public Interface
{
    public:
        virtual void BaseFunction(){}
};

class Derived : public Base
{
    public: 
        virtual void DerivedFunction(){}
};

int main()
{
    Derived derived;
}
如果您想只实现其中一个,请将
接口
分成两个接口:

class DerivedInterface
{
    public:
        virtual void DerivedFunction() = 0;
};

class BaseInterface
{
    public:
        virtual void BaseFunction() = 0;
};

class Base : public BaseInterface
{
    public:
        virtual void BaseFunction(){}
};

class Derived : public DerivedInterface
{
    public: 
        virtual void DerivedFunction(){}
};  

class Both : public DerivedInterface, public Base {
    public: 
        virtual void DerivedFunction(){}
};

int main()
{
    Derived derived;
    Base base;
    Both both;
}
注意:main必须返回int

注意:将
virtual
放在派生函数中的成员函数前面是一个很好的做法,即使它不是严格要求的。

问题是,在您的示例中,您有两个
接口的实现,一个来自
Base
,另一个来自
Derived
。这是用C++语言设计的。如前所述,只需删除
派生的定义上的
接口
基类

看起来派生的“is-a”基类并不完全相同,这表明包含可能是比继承更好的实现

此外,派生成员函数也应标记为虚拟

class Contained
{
    public:
        void containedFunction() {}
};

class Derived
{
    public:
        virtual void derivedFunction() {}
        virtual void containedFunction() {return contained.containedFunction();}
    private:
        Containted contained;
};

如果要隐藏实现细节,可以将包含的成员设为引用或智能指针。

我同意litb的回答。然而,这里有机会了解虚拟函数和多重继承是如何工作的

当一个类有多个基类时,每个基类都有单独的vTable<代码>派生的
将具有如下所示的vtable结构:

Derived
 vtable: Interface
   BaseFunction*
   DerivedFunction*
 vtable: Base
   BaseFunction*
Derived
 vtable: Interface
   BaseFunction* = 0
   DerivedFunction* = Derived::DerivedFunction
 vtable: Base
   BaseFunction* = Base::BaseFunction
此外,每个基类只能看到自己的vtable。当实例化
Base
时,它将填充vtable中的
Base::BaseFunction
指针,但看不到接口的vtable

如果您提供的代码可以编译,
Derived
实例的结果vtable结构如下所示:

Derived
 vtable: Interface
   BaseFunction*
   DerivedFunction*
 vtable: Base
   BaseFunction*
Derived
 vtable: Interface
   BaseFunction* = 0
   DerivedFunction* = Derived::DerivedFunction
 vtable: Base
   BaseFunction* = Base::BaseFunction

我发现利特的回答缺少一点。如果我有一个
派生的
实例,我可以得到一个
DerivedInterface
BaseInterface
。但是如果我只有一个
DerivedInterface
我就不能得到
BaseInterface
,因为从
BaseInterface
派生
DerivedInterface
是不起作用的

但是,由于某些原因,我一直限制自己进行编译时检查。这个
DerivedInterface
非常有效:

class DerivedInterface
{
    public:
        virtual void DerivedFunction() = 0;
        BaseInterface* GetBaseInterface()
            {return dynamic_cast<BaseInterface*>(this);}
};

void main()
{
    Derived derived;

    DerivedInterface* derivedInterface = &derived;
    derivedInterface->GetBaseInterface()->BaseFunction();
}
类派生接口
{
公众:
虚空DerivedFunction()=0;
BaseInterface*GetBaseInterface()
{返回动态_cast(this);}
};
void main()
{
派生的;
DerivedInterface*DerivedInterface=&derived;
derivedInterface->GetBaseInterface()->BaseFunction();
}

派生中不需要传递函数,每个人都很高兴。当然,它不再是一个严格意义上的接口,但这很好。为什么我没早点想到呢?:)

如果这样做,那么就不需要第二次声明BaseFunction,这是他写的。我不想改变它。他可能有理由这样做。没问题,我只是不想让他或其他人认为这是必要的,经历永恒2个问题:-现在不能自己实例化BAse。-从基派生的其他类现在必须实现派生函数类OtherDerived:public base{public:void OtherDerivedFunction(){};我编辑了代码。我并不是想把第二个基本功能声明。。不再次检查代码。基不从接口继承。(接口有DerviceFunction,它没有在Base中实现)这没有问题。您只需使一个类派生自DerivedInterface和BaseInterface,然后您就拥有了原始问题中“接口”类的接口。永远不要像那样使用dynamic_cast:)dynamic_cast应该是解决通过设计正确的接口无法解决的问题的最后手段。在您的情况下,只需按照我在上面的评论中所说的那样执行Interface,然后就可以执行BaseInterface*BaseInterface=&derived;并调用两者:)是的,这将给我相同的接口,但不同的实现,这就是重点。我有一个基类和派生类的实现,我需要一个接口。这听起来像是我将得到的最接近的结果。等等,我指的是“两者”类,它定义了自己的实现。嗯。