基类或派生类:谁应该拥有派生的ptr(到另一个类)

时间:2011-09-19 01:49:34

标签: c++

Child1是从BaseClass派生的十几个类之一。 Bar1是源自TFoo的十几个类之一。从BaseClass派生的所有对象都将具有指向从类TFoo派生的对象的指针。

问题:这被认为是更好的形式:

1)让基类拥有一个指向基类对象(TFoo)的指针,并且具有 派生的clases(Child1,Child2等)将TFoo指针向下转换为他们使用和拥有的实际派生类型

OR

2)让派生类(Child1,Child2等)拥有指向派生类(Bar1,Bar2等)的指针,并在基类中使用纯虚函数来访问upcast TFoo *?

(下面的例子是简化的 - 不是在语法上完美)

示例1:

class BaseClass
{
public:
    TFoo*   GetFoo(void)    { return mpFoo; }

protected:
    TFoo*   mpFoo;
};


class Child1 : public BaseClass
{
public:

    Bar1*   GetBar1(void)   { return (Bar1*)mpFoo; }
};


class Child2 : public BaseClass
{
public:
    Bar2*   GetBar2(void)   { return (Bar2*)mpFoo; }
};

示例2:

class BaseClass
{
public:
    virtual TFoo*   GetFoo(void) = 0;
};


class Child1 : public BaseClass
{
public:

    virtual TFoo*   GetFoo(void)    { return (TFoo*) mpBar; }

    Bar1*   GetBar(void)    { return mpBar; }

protected:
    Bar1*   mpBar;
};


class Child2 : public BaseClass
{
public:

    virtual TFoo*   GetFoo(void)    { return (TFoo*) mpBar2; }

    Bar2*   GetBar(void)    { return mpBar2; }

protected:
    Bar2*   mpBar2;
};

2 个答案:

答案 0 :(得分:3)

  

从BaseClass派生的所有对象都有一个指向从类TFoo派生的对象的指针。

如果这确实是所有派生类的要求,通常最好直接在基类中实现它,如果可能的话,要求每个派生类实现它。

另一个明确的观点:

  

Child1是从BaseClass派生的十几个类之一。

考虑示例2创建的所有复制代码。给出两个选项,其中一个导致大量复制代码,但另一个没有,我几乎总是选择没有所有复制代码的选项。每个副本代表一个人可能犯错误的地方。此外,如果您决定更改GetFoo()的含义,该怎么办?一份=一次更改。几十个拷贝=几十个变化。

答案 1 :(得分:0)

施法很容易出错,应尽可能避免。您应该考虑使用方法2,除非效率是主要考虑因素(避免虚函数调用)。在任何一种情况下,您都可以使用模板来避免冗余:

template <typename Bar>
struct BasicChild : BaseClass {
  virtual TFoo* GetFoo() const { return mpBar; }
  Bar* GetBar() const { return mpBar; }

  protected:
     Bar* mpBar;
};

struct Child1 : BasicChild<Bar1> { }
struct Child2 : BasicChild<Bar2> { }