2

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

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,这意味着我无法将函数的实现与头文件分开。

4

3 回答 3

3

听起来模板确实是大材小用,某种形式的依赖注入更合适。您可以将 in 的特定实例传递XA::init,例如:

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

或者传入一个工厂函数:

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

或者执行其中任何一项,但将实例或工厂函数传递给A.

于 2012-12-03T20:25:23.127 回答
2

...即使我只需要以一种方法使用它...

在这种情况下,通常所做的是将未模板化的通用功能移至基类,并定义一个A继承基本功能的模板化。IE:

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,可以make virtual

于 2012-12-03T20:33:57.373 回答
2

如果从使用中看起来new,它实际上是map<int, X*> mand X* bla=...,你可以“模板化”just init(),创建一个YorZ取决于它的模板参数。

或者,您可以为X派生对象提供工厂方法,该方法返回Y *Z *取决于enum; 或者让调用者init指定一个返回适当X派生类型的工厂函数。

于 2012-12-03T20:24:59.330 回答