Child1是从BaseClass派生的十几个类之一。 Bar1是源自TFoo的十几个类之一。从BaseClass派生的所有对象都将具有指向从类TFoo派生的对象的指针。
问题:这被认为是更好的形式:
1)让基类拥有一个指向基类对象(TFoo)的指针,并且具有 派生的clases(Child1,Child2等)将TFoo指针向下转换为他们使用和拥有的实际派生类型
OR
2)让派生类(Child1,Child2等)拥有指向派生类(Bar1,Bar2等)的指针,并在基类中使用纯虚函数来访问upcast TFoo *?
(下面的例子是简化的 - 不是在语法上完美)
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; }
};
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;
};
答案 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> { }