我想知道我是否可以将一个类分配给特定的成员数据并创建该类的实例



我想知道这是否可能。

我在一个项目中有一个类。

class A { ...
void CreateInternal(void);
B* m_pData;
... }
void A::CreateInternal(void)
{
m_pData= new B;
}

在其他项目中,我添加了 C 类,并希望像这样在 A::CreateInernal(void( 中制作它......

void A::CreateInternal(void)
{
m_pData = new C; // ex) B is base class of C
}

当然,我可以将A类设置为模板类,但是,我不想要它。我想最后使用它。(假设依赖或其他构建错误是免费的(

typename<class T>
class A { ...
void CreateInternal(void);
T* m_pData
... }
void A<T>::CreateInternal(void)
{
m_pData = new T;
}

我只想在 A 类中注册 B 类或 C 类。 可能吗??

感谢您的回复!

如注释中所述:

  1. 您不想使 A 成为模板类。
  2. 要创建实例的类共享一个公共基类,这也是成员指针的类型(以下前提条件!

因此,您可以将createInternal改为模板函数

template <typename T>
void A::createInternal()
//   ^^^ A still is a normal class!
{
m_data = new T();
// (will fail if T is a different type NOT inheriting
// from the base class in question)
}

旁注:通常,如果在类中提供了模板函数,则必须在头文件中实现它们(通常至少,有解决方法...(,如果createInstance私有的,但是,并且您不从公共内联函数调用它,则可以安全地在源文件中实现它,并且此文件将是使用该模板的唯一位置。

您甚至可以更进一步,允许使用可变参数模板调用所有可能的构造函数:

template <typename T, typename ... TT>
void A::createInternal(TT&& ... tt)
{
m_data = new T(std::forward(tt)...);
// (will fail, if there is no matching constructor
// for the arguments provided)
}

好的,您现在必须指定要创建的实例:

void A::f()
{
createInternal<B>();
createInternal<C>();
}

我认为这是可以接受的,因为您需要能够以某种方式分辨出您实际想要创建哪种类型。

另一种选择是不同的类(createInternalBcreateInternalC(的不同函数,但这肯定不那么优雅。

旁注:

可能吗??

即使你的类共享一个公共基类,你仍然可以存储在std::variant中创建的对象,或者,如果你碰巧编译了 pre-C++11,甚至在联合中(但你需要自己注意实际存储的类型——在这方面,std::variant更安全, 所以尽可能喜欢它(。

新评论更新:

如果您希望能够在 A 中创建任意对象而不必知道实际创建了哪个对象,现在提供另外两种选择:

在第一种变体中,您可以在 A 中createInternal虚拟(甚至可能是纯虚拟(,然后在派生类中重写以提供适合您需求的对象。

在第二个变体中,您提供了某个对象提供程序类的实例;假设DB : public DA : public D的基类,因此解决方案可能如下所示:

class A
{
public:
class ObjectProvider
{
public:
virtual ~ObjectProvider() = default;
public: virtual D* createInstance() = 0;
};
template <typename T>
class TheObjectProvider : public ObjectProvider
{
public:
D* createInstance() override
{
return new T();
}
};
A(std::unique_ptr<ObjectProvider> p)
: objectProvider(std::move(p))
{ }
private:
std::unique_ptr<ObjectProvider> objectProvider;
std::unique_ptr<D> m_data;
void createInternal()
{
m_data = objectProvider->createInstance();
}
};

用法:

A ab(std::make_unique<A::ObjectProvider<B>());
// your own custom object provider:
class OP : public A::ObjectProvider
{
public:
C* createInstance() override { return new C(); }
};
A ac(std::make_unique<OP>());

std::unique_ptras 参数(尽管通常不建议使用 smart 指针(现在有一个重要的功能:它表示类将获得传递对象的所有权,即 Herb Sutter 措辞中的一个接收器 - 参见他的 GotW91(。

如果您有最常用的数据类型(例如B(,您可以提供一个重载的默认构造函数,为此类型提供对象提供程序(或者可能是基类型D,如果不是抽象的(。

相关内容

最新更新