【发布时间】:2017-04-05 13:33:10
【问题描述】:
我试图从本网站的其他问题中了解我的情况,但我还没有真正找到一个好的答案。我尝试了我发现的大多数建议,但仍然遇到相同的错误。
我正在尝试实现一个基于单例和 CRTP 的工厂。所以我有一个 Singleton 类,在 Singleton.h 中定义:
template<class T>
class Singleton
{
public:
static T &instance()
{
static T one;
return one;
}
Singleton(const Singleton &) = delete;
Singleton(Singleton &&) = delete;
Singleton &operator=(const Singleton &) = delete;
protected:
Singleton() = default;
};
我还有一个 Factory 类,在 Factory.h 中定义和实现。工厂创建层次结构的对象,就本问题而言,其基类是Object。这些对象都有一个接受double的构造函数。
class Factory : public Singleton<Factory>
{
friend class Singleton<Factory>; // to access constructor
public:
using createFunction = Object *(*)(double);
void registerObject(const std::string &, createFunction);
Object *createObject(const std::string &, double) const;
private:
Factory() = default;
std::map<std::string, createFunction> theCreatorFunctions;
};
void Factory::registerObject(
const std::string &ObjectId,
createFunction creatorFunction)
{
theCreatorFunctions.insert(
std::pair<std::string, createFunction>(
ObjectId, creatorFunction));
}
Object *Factory::createObject(
const std::string &ObjectId, double a) const
{
auto it = theCreatorFunctions.find(ObjectId);
if (it == theCreatorFunctions.end())
{
std::cout << ObjectId << " is an unknown object."
<< std::endl;
return nullptr;
}
return (it->second)(a);
}
最后,我有一个“助手”类,可以将新类型的对象注册到工厂中。每次创建一个新的继承对象时,比如ObjectDerived,我都会添加(在实现ObjectDerived 的.cpp 文件中):
FactoryHelper<ObjectDerived> registerObjectDerived("ObjectDerived");
这将创建一个FactoryHelper<ObjectDerived> 类型的对象,其构造函数处理工厂中的注册。 FactoryHelper 在FactoryHelper.h 中定义(并实现):
template<class T>
class FactoryHelper
{
public:
FactoryHelper(const std::string &);
static Object *create(double);
};
template<class T>
FactoryHelper<T>::FactoryHelper(const std::string &ObjectId)
{
Factory &theFactory = Factory::instance(); // the one and only!
// if it doesn't exist at this point, it is created.
theFactory.registerObject(ObjectId, FactoryHelper<T>::create);
}
template<class T>
Object *FactoryHelper<T>::create(double a)
{
return new T(a);
}
所以我遇到的问题是我得到了一堆对Factory::instance() 的未定义引用,基本上每个层次结构中的每种类型的对象都有一个。
如果我将所有内容放在同一个 main.cpp 文件中,它可以工作,但这不是我想要的解决方案。
【问题讨论】:
-
我无法重现您的错误。为了使您的代码完整,我在一个文件中添加了一个非常简单的 Object 类和 main() 函数。当然,我没有创建继承自 Object 的类的层次结构。您能否通过提供最小的基础对象和派生类以及主函数来创建一个 MCVE 来显示您的问题,并包含编译器错误?
-
@jwimberley 我实际上只是做了同样的事情,并且不得不编辑我的问题,因为显然我之前做错了什么:将所有内容放在同一个 cpp 文件中不会产生错误。但这并不是一个理想的解决方案,真的。
-
在这种情况下,这似乎是编译/链接问题,而不是您的代码问题。
标签: c++ templates design-patterns singleton factory