gpt4 book ai didi

c++ - Factory 类的典型 C++ 实现是否存在缺陷?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:58:53 27 4
gpt4 key购买 nike

我需要在 C++ 中实现工厂类,但是当我思考这个问题时,我发现了一个我无法解决的大问题,我发现周围所有的工厂实现示例都存在相同的缺陷方法。可能是我错了,但请告诉我原因。

所以这是简单的“典型”工厂实现,它允许我在不更改工厂类的情况下注册新对象。

//fruit.h
class Fruit
{
protected :
int count;
public :
Fruit(int count) : count(count) {}
virtual void show() = 0;
};

// factory.h
/** singleton factory */
class Factory
{
typedef Fruit* (*FruitCreateFunction)(int);
static Factory* factory;
std::map<std::string, FruitCreateFunction> registeredFruits;
public :
static Factory& instance()
{
if (factory == NULL)
factory = new Factory();
return *factory;
}
bool registerFruit(const std::string& name, Fruit* (createFunction)(int))
{
registeredFruits.insert(std::make_pair(name, createFunction));
return true;
}
Fruit* createFruit(const std::string& name, int count)
{
return registeredFruits[name](count);
}
};

//factory.cpp
Factory* Factory::factory = NULL;

//apple.h
class Apple : public Fruit
{
static Fruit* create(int count) { return new Apple(count); }
Apple(int count) : Fruit(count) {}
virtual void show() { printf("%d nice apples\n", count); };
static bool registered;
};

// apple.cpp
bool Apple::registered = Factory::instance().registerFruit("apple", Apple::create);

//banana.h
class Banana : public Fruit
{
static Fruit* create(int count) { return new Banana(count); }
Banana(int count) : Fruit(count) {}
virtual void show() { printf("%d nice bananas\n", count); };
static bool registered;
};

// banana.cpp
bool Banana::registered = Factory::instance().registerFruit("banana", Banana::create);

// main.cpp
int main(void)
{
std::vector<Fruit*> fruits;
fruits.push_back(Factory::instance().createFruit("apple", 10));
fruits.push_back(Factory::instance().createFruit("banana", 7));
fruits.push_back(Factory::instance().createFruit("apple", 6));
for (size_t i = 0; i < fruits.size(); i++)
{
fruits[i]->show();
delete fruits[i];
}
return 0;
}

好吧,这段代码看起来很花哨而且可以工作,但是这里来了:

C++ 标准不允许我定义全局(静态)变量的定义顺序。

我这里有 3 个静态变量

Apple::registered;
Banana::registered;
Factory::factory;

Factory::factory 指针需要在 Apple(或 Banana)::registered 变量或Factory::instance 方法将使用未初始化的值,并且行为不可预测。

那么,我没有得到什么?代码真的只是偶然工作吗?如果是这样,我应该如何解决这个问题?

最佳答案

在任何初始化程序运行之前,保证所有全局 POD 数据都被初始化为常量值。

因此在程序开始时,在进行任何寄存器调用之前和运行 main 之前,指针自动为 NULL,并且所有 bool 值都为假。然后初始化程序运行,包括您的注册调用。

编辑:具体来说,来自标准(3.6.2.2:非本地对象的初始化):

Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. Static initialization shall be performed before any dynamic initialization takes place.

关于c++ - Factory 类的典型 C++ 实现是否存在缺陷?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3951732/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com