如何将类型名传递给我不想模板化的类?

How can I pass typename to a class that I don't want to templatize?

本文关键字:我不想 类型      更新时间:2023-10-16

我有以下问题(简化版):

Interface X;
class Y : public X { ... }
class Z : public X { ... }
class A
{
    map<int, X> m;
    init() { X bla = new Y or Z; map.insert(...) }
}

我想在创建 A 时指定 Y 或 Z,从而根据指定的类型获得不同的功能。目前我可以"模板化"A,但这意味着我为 A 定义的每个函数都必须指定模板,即使我只需要在一种方法中使用它。此外,我使用的是 g++ 4.2.4,这意味着我无法将函数的实现与头文件分开。

听起来模板确实是矫枉过正,某种形式的依赖注入更合适。您可以将X的特定实例传递给A::init,例如:

init(X &bla) { map.insert(...); }

或者传入工厂函数:

init(X (*factory)()) { X bla = factory(); map.insert(...); }

或者执行其中任何一个,但将实例或工厂函数传递给 A 的构造函数。

。即使我只需要在一种方法中使用它......

在这种情况下,通常要做的是将未模板化的通用功能移动到基类,并定义继承基功能的模板化A。 即:

class A_base {
    // common things go here, they can be implemented in a .cpp file.
};
// This is the part that depends on T
template<class T>
class A : public A_base
{
    map<int, T> m;
    void init() { T *bla = new T; map.insert(...) }
};

这是减少代码膨胀的常用技术。如果A_base需要调用A的方法,可以将其设为virtual

如果,从new的使用来看,它实际上是map<int, X*> mX* bla=...,你可以"模板化"只是init(),根据其模板参数创建一个YZ

或者,你可以有一个工厂方法用于X派生对象,该方法根据enum返回Y *Z *;或者让init的调用者指定一个返回适当的X派生类型的工厂函数。

相关文章: