C++多重继承 - 相同的方法名称 - 我可以以某种方式删除其中一个吗?

Mar*_*rry 5 c++ inheritance c++11

我在C++ 11中有这种结构

struct A {
   int idA;   
   void setId(int i) { idA = i;}
   int getId() { return idA;}

   virtual void foo() = 0;
};

struct B {
   int idB;   
   void setId(int i) { idB = i;}
   int getId() { return idB;}

   virtual void foo2() = 0;
};

struct AB : public A, public B
{
   void foo() override {}
   void foo2() override {}
};
Run Code Online (Sandbox Code Playgroud)

现在在main中我可以这样称呼它:

AB * ab = new AB();
ab->B::setId(10);
Run Code Online (Sandbox Code Playgroud)

但我真的不喜欢它.

还有其他解决方案吗?方法setId/getId来自struct A于不需要AB.我只是做了继承,因为我需要foo()和其他东西A,但所有其他方法都是独一无二的.

Ben*_*fan 8

既然你说你不需要A这些方法的版本,你可以写

struct AB : public A, public B
{
    void foo() override {}
    void foo2() override {}

    using B::setId;
    using B::getId;
};
Run Code Online (Sandbox Code Playgroud)

这将把B这些方法的实现放入AB命名空间并使它们明确地调用它们.

  • 这种方法的一个问题是,在这种情况下,`A::setId` 仍然会被调用:`A* ab = new AB(); ab->setId(0);` (4认同)

Res*_*ion 7

包装器转发方法怎么样:

struct AB : public A, public B
{
public:
    void setAId(int i) { A::setID(i); }
    void setBId(int i) { B::setID(i); }
};
Run Code Online (Sandbox Code Playgroud)

这样您就不会成为隐藏名称的“受害者”,您的意图在代码中变得清晰,并且您的名称反映了它们的作用,并且您不需要明确访问基类的成员。

另外,您可以创建另一个基类,并在这两个几乎继承它A,并B在其中将包含setId方法。


Mat*_*ndt 5

只要您调用setId(int)AB 类型的对象或 AB 指针(当然大多数情况下),接受的答案就可以工作。但如果你想调用该函数,A* ab = new AB();你必须显式覆盖它。

struct A {
   int idA;   
   virtual void setId(int i) { idA = i;}
};

struct B {
   int idB;   
   virtual void setId(int i) { idB = i;}
};

struct AB : public A, public B
{
    void setId(int i) override { B::setId(i); }
};
Run Code Online (Sandbox Code Playgroud)