如果基类有2个派生类,并且每个类都有派生类,那么我可以为大多数派生类扩展一个基本方法*一次吗?

时间:2014-10-13 15:44:31

标签: c++ inheritance

对于罗嗦的标题感到抱歉。这是我正在使用的继承方案的pseduocode,假设C ++和公共继承:

ClassA
ClassB : ClassA
ClassC : ClassA
ClassBB : ClassB
ClassCC : ClassC

我想覆盖ClassAClassBB ClassCC中定义的方法。但我只能使用ClassBBClassCC或新课程。

我知道我可以延长ClassA,但我需要更改ClassBClassC的定义(依次为ClassBBClassCC)看到变化。有了这个限制,我认为我在ClassBBClassCC都重复了覆盖。还有其他办法吗?

3 个答案:

答案 0 :(得分:1)

您可以实现一次全局函数模板,并在ClassBBClassCC中覆盖函数的定义中调用它。然后,您只需要编写一次实现。这里有一些未经测试的代码:

struct A
{
     virtual void foo() {}
};
struct B : public A {};
struct C : public A {};

template<typename T>
void foo_impl(T const& t)
{
     //do something with t
};    

struct BB : public B
{
     virtual void foo() { foo_impl(*this); }
};

struct CC : public C
{
     virtual void foo() { foo_impl(*this); }
};

答案 1 :(得分:0)

如果您不需要访问Base类中的任何受保护成员,只需委托外部函数,可能是上一个答案中建议的模板。

否则,您可以使用多个虚拟继承:

#include <iostream>

class Base
{
public:
    virtual void foo() {std::cerr << "Base::foo: " << (++i) << std::endl;};
    Base() : i(0) {}
    virtual ~Base() {}
protected:
    int i; // the state that you need to access in foo()
};

class Implement: public virtual Base
{
public:
     void foo() override {std::cerr << "Implement::foo: " << (++i) << std::endl;}
};

class D1: public Base{};
class D2: public Base{};

class DD1: public D1, public Implement
{
public:
    virtual void foo() override {Implement::foo();}
};

class DD2: public D2, public Implement
{
public:
    virtual void foo() override {Implement::foo();}
};

int main()
{
    DD1 dd1;
    dd1.foo();
    D1 &d1r = dd1;
    d1r.foo();
    D1 d1;
    d1.foo();
}

一个限制是您最终会为DD1和DD2实例添加一个模糊的Base类

@Ben Voigt建议广告,CRPT是解决同一问题的一个很好的替代方案,不受模糊基类的限制:

template <class D>
class CRTP
{
protected:
    void foo_impl(D &d) {std::cerr << "CRTP::foo_impl: " << (++d.i) << std::endl;}
};

class DD2: public D2, public CRTP<DD2>
{
public:
    virtual void foo() override {CRTP<DD2>::foo_impl(*this);}
    friend class CRTP<DD2>;
};

答案 2 :(得分:0)

由于您未指定班级A中的功能是否为虚拟,我们有两种可能性。

如果foo不是虚拟的,并且您不需要使用BB指向A的指针(同样适用于CCC):

class A { public: void foo(); }

class B : public A {} // `A::foo` can be accessed from B.

class BB : public B
{
public:
  // Problem (1): `A::foo` can be accesed from B, and `BB::foo` is another function.
  void foo() { <other_behaviour> } 
};

为了避免问题(1),您可以将A::foo设为私有:

class A { public: void foo(); }

class B : public A {} // `A::foo` can be accesed from B.

class BB : public B
{
public:
  void foo() { <other_behaviour> } 

private:
   using A::foo; // `A::foo` can't be accessed from B.
};

在这种情况下,您现在有两个功能:A::fooB::foo,但无法从A::foo访问B

如果您需要使用BB::foo()指针指向A(或B),或A::foo已经是虚拟的:

class A { public: virtual void foo(); }

class B : public A {} // `A::foo` can be accessed from B.

class BB : public B
{
public:
  // Problem (2): `A::foo` and `B::foo` are two different functions, but for using `A::foo`,
  // the user must write `A::foo()` to call it, and don't simply `foo()`.
  void foo() { <other_behaviour> } 
};

要解决(2),您也可以这样做,A::foousing私有。在这两种情况下,B(和C)都不需要更改,在第一种情况下,A也是如此。