具有相同名称的纯虚函数的不同实现

use*_*802 6 c++ gcc visual-c++

可能重复:
继承共享方法名称的接口

我有两个基类I1I2纯虚函数void R() = 0;.我想在派生类IImpl要继承I1I2并有不同的实现方式为I1::R()I2::R().

下面的代码在MS VS 2005和2010中编译和工作.我在禁用语言扩展并且在警告级别4上进行编译.没有警告也没有错误.

我在gcc 4.2中尝试了相同的代码.它不编译.GCC报告错误:

error: cannot define member function 'I1::R' within 'IImpl'
Run Code Online (Sandbox Code Playgroud)

我的问题是:

  1. 为什么代码在MS VS中工作以及为什么它在gcc中不起作用?
  2. 代码是标准C++吗?
  3. 实现它的正确方法是什么,所以它是一个标准的C++并在VS和gcc上编译?

谢谢!

#include <stdio.h>

class I1
{
public:
    virtual void R() = 0;
    virtual ~I1(){}
};

class I2
{
public:
    virtual void R() = 0;
    virtual ~I2(){}
};

class IImpl: public I1, public I2
{
public:

    virtual void I1::R()
    {
        printf("I1::R()\r\n");
    }

    virtual void I2::R()
    {
        printf("I2::R()\r\n");
    }
};

int main(int argc, char* argv[])
{
    IImpl impl;

    I1 *p1 = &impl;
    I2 *p2 = &impl;

    p1->R();
    p2->R();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Kon*_*hin 6

根据8.3/1,此代码是非标准的

除了在其类之外的成员函数(9.3)或静态数据成员(9.4)的定义之外,声明者id不应被限定,...

因此,在类中声明/定义成员函数名时,不能限定成员函数名.这就是为什么它不是由gcc编译的.

MSVC似乎有一个允许这样的代码的非标准扩展.我想它是针对C++的Managed Extensions完成的,这正是在那里进行显式接口实现的方式,尽管很久以前它已被弃用,但似乎仍然支持语法.

BjörnPollex 提供的链接描述了实现它的正确方法.


Obs*_*bot 2

您只能void R()在 中实施一次IImpl