Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.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++ 多重继承:2类1方法_C++ - Fatal编程技术网

C++ 多重继承:2类1方法

C++ 多重继承:2类1方法,c++,C++,我刚刚试过这段代码: struct FaceOfPast { virtual void Smile() = 0; }; struct FaceOfFuture { virtual void Smile() = 0; }; struct Janus : public FaceOfPast, public FaceOfFuture { virtual void Smile() {printf(":) ");} }; 它按预期工作(输出两个笑脸),但我认为它甚至不应该编

我刚刚试过这段代码:

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

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

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

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


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

没有歧义,因为在指向
FaceOfFuture
FaceOfPast
的指针上调用
Smile()
,这些指针只声明了一个方法
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();
}
尽管在
Janus
上调用
Smile
,基类声明还是隐藏的

以下内容不适用:

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();
}
因为模棱两可

Janus* j = new Janus();
FaceOfFuture* future = j;
FaceOfPast* past = j;
这段代码可以向下转换为基类。所以当你做下面的事情时

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

这是一个指向FACEFASEFACEFACEFUTURE的指针。

< P>根据C++标准(103.2):

如果虚拟成员函数vf在类Base和直接或间接从Base派生的类中声明,则成员函数vf具有相同的名称、参数类型列表、cv限定符和ref限定符(或没有相同的限定符)当声明Base::vf时,则派生::vf[…]重写Base::vf


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

问题似乎不在于调用部分,但是重新定义的部分:为什么只编写一个方法就可以从两个不同的类中重新定义两个同名的虚拟方法呢?
future->Smile();
past->Smile();