如果我从基类成员函数(使用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);
在一般情况下,这通常表明设计不好——基类通常不应该知道/关心它的派生类。
请注意,您可以返回一个指向Derive
的指针,类型为Base*
-这是工厂方法设计模式的原则。也许这适合您的实际场景?
但是请注意,所有规则都有例外。如果您的(基类派生类)表示一个紧密耦合且连贯的单元(例如具有两个子类FastTree
和SmallTree
的Tree
接口,针对不同目的进行了优化),则它们可以相互感知,并且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_ptr
或boost::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,反之亦然。