首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多重继承: 2Classes1Method

多重继承: 2Classes1Method
EN

Stack Overflow用户
提问于 2012-04-24 20:00:11
回答 3查看 135关注 0票数 10

我刚刚尝试了这段代码:

代码语言:javascript
复制
struct FaceOfPast
{
    virtual void Smile() = 0;
};

struct FaceOfFuture
{
    virtual void Smile() = 0;
};

struct Janus : public FaceOfPast, public FaceOfFuture
{
    virtual void Smile() {printf(":) ");}
};

..。

代码语言:javascript
复制
void main()
{
    Janus* j = new Janus();
    FaceOfFuture* future = j;
    FaceOfPast* past = j;

    future->Smile();
    past->Smile();

    delete j;
}

它可以正常工作(输出两个笑脸),但我认为它甚至不应该编译,在Janus中重新声明Smile()是模棱两可的。

它是如何(以及为什么)工作的?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-24 20:05:42

不会有歧义,因为您可以在指向FaceOfFutureFaceOfPast的指针上调用Smile(),而这些指针只声明了一个方法Smile()

因为在基类指针上调用该方法不会导致多义性,所以让我们来看看直接在子类指针上调用该方法时的情况

代码语言:javascript
复制
Janus* j = new Janus();
j->Smile();

除了覆盖之外,派生类还隐藏了基类的Smile()声明。只有当你不想重写派生类中的方法时,你才会有歧义:

以下代码将进行编译:

代码语言:javascript
复制
struct FaceOfPast
{
    virtual void Smile() {printf(":) ");}
};
struct FaceOfFuture
{
    virtual void Smile() {printf(":) ");}
};
struct Janus : public FaceOfPast, public FaceOfFuture
{
   virtual void Smile() {printf(":) ");}
};
int main()
{
   Janus* j = new Janus();
   j->Smile();
}

尽管您在Janus上调用Smile,但基类声明是隐藏的。

以下内容则不适用:

代码语言:javascript
复制
struct FaceOfPast
{
    virtual void Smile() {printf(":) ");}
};

struct FaceOfFuture
{
    virtual void Smile() {printf(":) ");}
};

struct Janus : public FaceOfPast, public FaceOfFuture
{
};

int main()
{
   Janus* j = new Janus();
   j->Smile();
}

因为模棱两可。

票数 7
EN

Stack Overflow用户

发布于 2012-04-24 22:38:42

根据C++标准(10.3.2):

如果在类基本和类派生中声明虚拟成员函数vf,则声明具有与<代码>E19基类::vf<代码>E210相同的名称、参数类型列表、cv限定和引用限定符(或缺少相同)的成员函数vf,则<代码>E111派生::vf<代码>E212 ...重写Base::vf

对于多重继承似乎没有任何特殊的处理,所以它很可能也适用于这里:void Janus::Smile()覆盖了这两个方法,没有任何歧义,只是因为它与两个基类方法具有完全相同的名称和签名。

票数 1
EN

Stack Overflow用户

发布于 2012-04-24 20:48:31

代码语言:javascript
复制
Janus* j = new Janus();
FaceOfFuture* future = j;
FaceOfPast* past = j;

这段代码将向下转换为一个基类。因此,当您执行以下操作时

代码语言:javascript
复制
future->Smile();
past->Smile();

这实际上是指向FaceofPast和FaceOfFuture的指针。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10297405

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档