我刚刚尝试了这段代码:

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

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

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

...
void main()
{
    Janus* j = new Janus();
    FaceOfFuture* future = j;
    FaceOfPast* past = j;

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

    delete j;
}

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

它如何(为什么)起作用?

最佳答案

毫无疑问,因为您在仅声明一种方法Smile()FaceOfFutureFaceOfPast指针上调用Smile()

因为在基类指针上调用方法不会导致歧义,所以让我们处理直接在子类指针上调用方法的情况:

Janus* j = new Janus();
j->Smile();

除了覆盖之外,派生类还隐藏了Smile()的基类声明。仅在不覆盖派生类中的方法的情况下,您才有歧义:

编译如下:
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();
}

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

以下不是:
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();
}

因为模棱两可。

10-04 14:25