为什么我不能在多重继承 C++ 中使用 `using`?

Why can't I use `using` in a multiple inheritance c++?

我尝试实现一些接口及其子接口。这是我的想法:

         Interface
         /       \
  Interface2    InterfaceDefination
        |        /
  Interface2Defination  

这是我的代码:

#include <iostream>

class Interface {
public:
  virtual void method1() = 0;
  virtual void print() = 0;
};

class Interface2 : public Interface {
public:
  virtual void method2() = 0;
};

class InterfaceDefination : public Interface {
public:
  virtual void method1() override {
    std::cout << "method1 from InterfaceDefination\n";
  }
};

class Interface2Defination : public Interface2, public InterfaceDefination {
public:
  using InterfaceDefination::method1;
  virtual void print() override {
    std::cout << "print from Interface2Defination\n";
  }
  virtual void method2() override {
    std::cout << "method2 from Interface2Defination\n";
  }
};

int main() {
  Interface2Defination c;
  c.method1();
  c.method2();
  c.print();
}

我的预期输出是:

method1 from InterfaceDefination
method2 from Interface2Defination
print from Interface2Defination

但我不小心收到了这些错误:

main.cpp:33:24: error: variable type 'Interface2Defination' is an abstract class
  Interface2Defination c;
                       ^
main.cpp:5:16: note: unimplemented pure virtual method 'method1' in 'Interface2Defination'
  virtual void method1() = 0;
               ^
1 error generated.
make: *** [<builtin>: main.o] Error 1
exit status 2

https://godbolt.org/z/9ncoGfn4P

在这种情况下,错误意味着 using 关键字没有使方法 method1 在 class Interface2Defination 中可用。我应该用它做什么?

照这样,Interface2Defination中有两个Interface::method1,只有其中一个有实现。如果您实际上继承了 Interface,那么您就有了一个定义。

#include <iostream>

class Interface {
public:
  virtual void method1() = 0;
  virtual void print() = 0;
};

class Interface2 : public virtual Interface {
public:
  virtual void method2() = 0;
};

class InterfaceDefination : public virtual Interface {
public:
  virtual void method1() override {
    std::cout << "method1 from InterfaceDefination\n";
  }
};

class Interface2Defination : public Interface2, public InterfaceDefination {
public:
  virtual void print() override {
    std::cout << "print from Interface2Defination\n";
  }
  virtual void method2() override {
    std::cout << "method2 from Interface2Defination\n";
  }
};

int main() {
  Interface2Defination c;
  c.method1();
  c.method2();
  c.print();
}

一个using声明是一个声明。它不是定义。它没有定义任何“新”的东西。它所做的是声明:好的,我有一个符号 X,但它实际上指的是我 parent class 中的 X(对于此版本的 using 声明)。

您可能会问这有什么意义,您不是以正常方式从 parent class 继承 X 吗?是的,确实如此,但这不是一回事,但技术差异在这里几乎无关紧要。

此处同样重要的是所示图表具有误导性。这是一种流行的描述(non-virtual)钻石继承的方式,但每次显示都是 100% 错误。这是因为 Interface2Defination 不继承 one 个实例 Interface,而是 两个。这是一个更准确的继承图:

  Interface          Interface
       |                |
  Interface2    InterfaceDefination
        |        /
  Interface2Defination

对于Interfaceparentclasses的两个实例中的每一个,只有一个 的抽象方法被定义和覆盖,因此显示的代码是 ill-formed.

using声明没有定义childclass中导入的方法,并正式覆盖它。 using 声明不计入覆盖抽象方法的目的。只有正式定义一个继承的抽象方法才能做到这一点,而不是声明一个。