从基类成员函数返回派生类的实例

时间:2014-03-03 07:56:16

标签: c++ inheritance

是O.K.设计,如果我从Base类成员函数返回Derived类的实例(使用new Derived()创建)?

此外,还需要转发声明Derived类,并将Derived类构造函数设为public。

代码示例: -

Class Base
{
 public:
  Base() {}
  Derived* get_new_derived(int X) 
  { 
    Derived *der = new Derived(X); 
    return der;  
  }
}

Class Derived : public Base
{
 private:
  int _X;
 protected:
  Derived(int X) { _X = X; }
 public:  
  Derived* get_new_derived(int X) 
  { 
    Derived *der = new Derived(X); 
    return der;  
  }
}

我还有一个派生类(比如Derived1)。现在让我们说: -

用法1:

Derived1* der1 = new Derived1();
Derived * der = der1->get_new_derived(10);

用法2:

Derived1* der1 = new Derived1();
Base* bs = der1;
Derived * der = bs->get_new_derived(10);

3 个答案:

答案 0 :(得分:3)

在一般情况下,这通常表示设计不良 - 基类通常不应该知道/关心其派生类。

请注意,您可以返回指向Derived Base*的指针 - 这是Factory Method设计模式的原理。也许这符合你的实际情况?

但请注意,所有规则都有例外。如果您的(基类+派生类)表示一个紧密耦合且一致的单元(例如Tree接口,其中包含两个子类FastTreeSmallTree,并针对不同目的进行了优化,则可以接受让他们彼此了解,并Tree定义以下功能:

std::unique_ptr<SmallTree> Tree::createSmallCopy() const
{
  return { new SmallTree(/*args*/) };
}

std::unique_ptr<FastTree> Tree::createFastCopy() const
{
  return { new FastTree(/*args*/) };
}

所以这取决于你的实际用例。我一般都对这种设计持谨慎态度,但它有其用途。


作为旁注,在现代C ++中,你永远不应该使用拥有的原始指针 - 使用像std::unique_ptrboost::shared_ptr这样的智能指针。

答案 1 :(得分:1)

是的,你可以做到。问题是你是否应该。

你不应该这样做,因为它暗示Base know Derived,这不是适当的面向对象设计。依赖关系应该是一种方式 - 派生知道Base而不是相反。

答案 2 :(得分:1)

这个怎么样?

// The Curiously Recurring Template Pattern (CRTP)
template<class Derived>
class Base
{
  // methods within Base can use template to access members of Derived
};
class Derived : public Base<Derived>
{
  // ...
};

http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern