提问者:小点点

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


如果我从基类成员函数(使用new Derive()创建)返回派生类的实例,它是一个好的设计吗?

这还涉及到需要前向声明派生类并使派生类构造函数公开。

代码示例:-

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个答案

匿名用户

在一般情况下,这通常表明设计不好——基类通常不应该知道/关心它的派生类。

请注意,您可以返回一个指向Derive的指针,类型为Base*-这是工厂方法设计模式的原则。也许这适合您的实际场景?

但是请注意,所有规则都有例外。如果您的(基类派生类)表示一个紧密耦合且连贯的单元(例如具有两个子类FastTreeSmallTreeTree接口,针对不同目的进行了优化),则它们可以相互感知,并且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

匿名用户

这个怎么样?

// 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

匿名用户

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

您不应该这样做,因为这意味着Base知道Derive,这不是正确的面向对象设计。依赖项应该是一种方式-派生知道Base,反之亦然。