C ++设计(基类中的行为,派生类中提供的私有成员)

时间:2011-10-11 18:15:39

标签: c++ inheritance composition

我有6个类都执行相同的操作。我想将共同行为转移到一个共同的[基础]类。

要对6个单独的对象执行操作。六个对象位于派生类中。直观地,私有成员对象将通过基类中的子(派生类)进行访问。

我正在寻找什么样的C ++模式?

class Base
{
  // Common behavior, operate on m_object
  ...
  void Foo()
  {
    m_object.Bar();
  }
};

class Derived1 : public Base
{
  // No methods, use Base methods

  private:
  MyObject1 m_object;
}

class Derived2 : public Base
{
  // No methods, use Base methods

  private:
  MyObject2 m_object;
}

让我陷入这种情况的是MyObject1MyObject2等提供Bar(),但不要共享一个共同的基类。我真的无法修复派生,因为对象来自外部库。

5 个答案:

答案 0 :(得分:5)

如果在派生类中引入它们,则基类不能直接访问它们。基类如何知道所有派生类都有特定的成员?

您可以使用虚拟保护方法,如下所示:

class my_base
{
protected:
    virtual int get_whatever();
    virtual double get_whatever2();
private:
    void process()
    {
       int y = get_whatever();
       double x = get_whatever2();
       //yay, profit?
    }
}

class my_derived_1 : my_base
{
protected:
    virtual int get_whatever()
    {
        return _my_integer;
    }

    virtual double get_whatever2()
    {
       return _my_double;
    }
}

另一种可能性(如果你想从派生类中调用基本方法)就是简单地为基本方法提供参数。

class my_base
{
protected:
    void handle_whatever(int & arg);
};

class my_derived : my_base
{
    void do()
    {
      my_base::handle_whatever(member);
    }

    int member;
};

答案 1 :(得分:1)

C ++有没有。它具有非常强大的多继承支持,因此没有super关键字。为什么?想象一下,你的基类是由另外两个类继承的,或者甚至是虚拟继承层次结构的一部分。在这种情况下,你无法真正说出super应该是什么意思。另一方面,有虚拟方法,你总是可以在基类中使用它们并在派生类中实现(这就像Java那样的语言,除了它们没有多个类继承支持)。如果你不想使用多态,你可以使用这样的东西:

#include <cstdio>

template <typename T>
struct Base
{
    void foo ()
    {
        std::printf ("Base::foo\n");
        static_cast<T *> (this)->bar ();
    }
};

struct Derived : Base<Derived>
{
    void bar ()
    {
        std::printf ("Derived::bar\n");
    }
};

int
main ()
{
    Derived d;
    d.foo ();
}

这是一个非常简单的例子 - 你可以使用访问控制,朋友,编译时断言等扩展上面的例子,但你明白了。

答案 2 :(得分:1)

您是否考虑过不使用继承?

class FooBar
{
   MyObject m_object;
public:
   FooBar(MyObject m): m_object(m) {}
   //operate on different m_objects all you want
};

答案 3 :(得分:0)

也许您只需要一个模板而不是超类和6个派生类?

您似乎不需要访问父级,而是访问子级字段。你应该通过引入抽象方法来实现:

class ParentClass
{
  public:
    void f();
  protected:
    virtual int getSomething() = 0;
};

ParentClass::f()
{
    cout << getSomething() << endl;
}

class DerivedClass : public ParentClass
{
  protected:
    virtual int getSomething();
}

DerivedClass::getSomething() { return 42; }

如果您需要访问父方法,只需使用ParentClass::method(...)

class ParentClass
{
  public:
    virtual void f();
};

class DerivedClass : public ParentClass
{
  public:
    virtual void f();
};

void DerivedClass::f()
{
    ParentClass::f();
}

答案 4 :(得分:0)

如何从公共基类派生六个独立的对象?然后,您可以在该基类中声明虚方法来创建您的接口,然后在派生对象类中实现它们。