【问题标题】:C++ virtual override functions with same name具有相同名称的 C++ 虚拟覆盖函数
【发布时间】:2011-03-10 04:23:09
【问题描述】:

我有类似的东西(简体)

class A
{
  public:
    virtual void Function () = 0;
};

class B
{
  public:
    virtual void Function () = 0;
};

class Impl : public A , public B
{
  public:
        ????
};

如何实现 A 的 Function () 和 B 的 Function() ? Visual C++ 允许您只定义特定的内联函数(即不在 cpp 文件中), 但我想这是一个扩展。 GCC 对此抱怨。 有没有标准的 C++ 方法来告诉编译器我要覆盖哪个函数?

(Visual C++ 2008)

class Impl : public A , public B
{
  public:
     void A::Function () {  cout << "A::Function" << endl; }
     void B::Function () {  cout << "B::Function" << endl; }
};

谢谢!

【问题讨论】:

  • 另外,我终于意识到在实现多个 COM 接口时 QueryInterface 是如何工作的! :)

标签: c++ virtual overriding diamond-problem


【解决方案1】:

您不能在此处使用限定名称。我你写void Function() { ... } 你正在覆盖 both 函数。 Herb Sutter 显示how it can be solved

另一种选择是重命名这些函数,因为它们显然做了不同的事情(否则我看不到以相同的行为覆盖 both 的问题)。

【讨论】:

    【解决方案2】:

    如果 A 和 B 是接口,那么我将使用虚拟派生来“加入”它们(使它们重叠)。如果您需要通过指向AB 的指针调用Function 的不同实现,那么我强烈建议您选择另一种设计。否则会很痛。

    Impl“派生自”AB 表示 Impl“是”AB。我想你不是这个意思。

    Impl“实现接口”AB表示Impl“表现得像”AB。那么相同的界面应该意味着相同的行为。

    在这两种情况下,根据所使用的指针类型具有不同的行为将是“精神分裂症”,并且肯定是要避免的情况。

    【讨论】:

    • 这里没有钻石。只有名字冲突。 A 和 B 可能来自不同的库。
    • @Alex 是的,这是错误的术语,命名空间冲突是合适的。
    • 虚拟派生在这里有什么帮助?
    【解决方案3】:

    作为一种解决方法,请尝试

    struct Impl_A : A
    { 
         void Function () {  cout << "A::Function" << endl; } 
    }; 
    
    
    struct Impl_B : B
    {
        void Function () { cout << "B::function" << endl; }
    };
    
    struct Impl : Impl_A, Impl_B {};
    

    【讨论】:

      【解决方案4】:

      我可以建议另一种方法来解决此问题。您可以添加包装器Typed,它通过添加虚拟参数来更改Function 签名。因此,您可以区分实现中的方法。

      class A {
      public:
        virtual void Function() = 0;
        virtual ~A() = default;
      };
      
      class B {
      public:
        virtual void Function() = 0;
        virtual ~B() = default;
      };
      
      template<typename T>
      class Typed : public T {
      public:
        virtual void Function(T* dummy) = 0;
        void Function() override {
          Function(nullptr);
        }
      };
      
      class Impl : public Typed<A>, public Typed<B> {
      public:
        void Function(A* dummy) override {
          std::cerr << "implements A::Function()" << std::endl;
        }
        void Function(B* dummy) override {
          std::cerr << "implements B::Function()" << std::endl;
        }
      };
      

      这种解决方案的好处是所有实现都放在一个类中。

      【讨论】:

        猜你喜欢
        • 2016-04-19
        • 1970-01-01
        • 2021-03-27
        • 1970-01-01
        • 1970-01-01
        • 2019-08-31
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多