#include <memory>
class Base
{
std::shared_ptr<Base> create() const; // Returns a default constructed object
}
假设从Base
派生到任何程度的所有成员都是可复制的,默认可构造的。我想要
std::shared_ptr<Base> create() const;
创建适当动态类型的对象的方法,但我不想使用样板代码。
有没有可能制作
std::shared_ptr<Base> create() const;
静态绑定,但在内部找到正确的类型并使用 Default 构造函数创建对象?可能使用 C++11。
create()
函数可能应该是静态的,因为您还没有实例。但是没有参数,你就不能做你想做的事......当然,除非您使用模板:
class Base
{
public:
template<typename T>
static std::shared_ptr<Base> create() const
{
return std::shared<Base>(new T);
}
};
然后以这种方式使用它:
std::shared_ptr<Base> ptr(Base::create<Foo>());
或者,如果您愿意:
std::shared_ptr<Base> ptr(Foo::create<Foo>());
理想情况下,您有一个静态的,也许是一个非静态的create()
函数。有一种聪明的方法可以实现这一点。
-
定义
SuperBase
类。它需要一个虚拟析构函数和一个纯虚拟create()
函数。你将使用指向此类的指针/引用来实现正常的后期绑定 OOP 行为。 -
定义从
SuperBase
继承的Base
类模板。Base
的模板参数将是Derived
类的类型。Base
还将有一个特征类模板,其中包含一个名为create()
的静态函数。此静态create()
函数将使用new
创建一个默认对象。使用 trait 的create()
函数,Base
将定义static_create()
和纯虚SuperBase::create()
函数。 -
通过继承
Base<Derived>
来实现Derived
。
如果您知道您正在使用派生类型,则可以编写Derived::create()
以静态创建新类型。如果没有,则始终可以使用实例的create()
方法。多态性不会中断,因为SuperBase
将具有您需要/想要的多态接口 - Base<D>
只是一个自动定义static_create()
和create()
函数的帮助程序类,因此您通常不会直接使用Base<D>
。
示例代码如下所示:
#include <memory>
#include <iostream>
class SuperBase
{
public:
virtual ~SuperBase() = default;
virtual std::shared_ptr<SuperBase> create() const = 0;
};
template <typename T>
struct Base_Traits
{
static T* create()
{
return new T;
}
};
template <typename Derived, typename Traits=Base_Traits<Derived>>
class Base : public SuperBase
{
public:
// Define a static factory function...
static std::shared_ptr<SuperBase> static_create()
{
return std::shared_ptr<SuperBase>{Traits::create()};
}
// Define pure virtual implementation...
std::shared_ptr<SuperBase> create() const override
{
return static_create();
}
};
class Derived : public Base<Derived>
{
};
int main()
{
auto newone = Derived::static_create(); // Type known @ compile time
auto anotherone = newone->create(); // Late binding; type not known @ compile time
}