gpt4 book ai didi

c++ - 从静态成员函数访问静态映射 - 段错误 - C++

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

我试图通过在静态映射(工厂成员)中将派生类的函数指针注册到工厂并通过查找映射创建对象来实现工厂模式。但是我在这样做时遇到了段错误。

代码片段:

工厂.cpp

typedef Shape* (*Funcptr)();

std::map<int,Funcptr> Factory::funcmap;

int Factory::registerCreator(int ShapeID, Shape *(*CFuncptr)()) {
Factory::funcmap[ShapeID] = CFuncptr;
return 1;
}

Shape* Factory::CreateObject(int ShapeID) {
std::map<int,Funcptr>::iterator iter;
iter = funcmap.find(ShapeID);
if(iter != funcmap.end()){
return iter->second();
}
return NULL;
}

工厂.h

class Factory {
public:
Factory();
virtual ~Factory();
static int registerCreator(int, Shape *(*CFuncptr)());
Shape* CreateObject(int);
private:
static std::map<int,Funcptr> funcmap;
};

正方形.cpp

static Shape *SquareCreator() { 
return new Square;
}
static int SquareAutoRegHook = Factory::registerCreator(1,SquareCreator);

在主文件中为 Factory 创建对象时发生段错误。如果我做错了什么,你能建议一下吗?我正在为 TDD 使用 CppUTest,但不确定如何调试它。

最佳答案

无法保证以不同翻译 uint* 定义的静态对象的创建顺序*,因此您有 50/50 的概率先发生,即 Factory::funcmap 的初始化或 Factory::registerCreator(1,SquareCreator)和未定义行为俄罗斯轮盘赌不是一个好游戏。

处理此问题的常用方法,以及在 the third edition of Scott Meyer's Effective C++ 的第 4 项中描述的方法就是使用局部静态对象而不是全局静态对象。在这种情况下,它意味着改变 Factory看起来像这样:

class Factory { 
public:
Factory();
virtual ~Factory();
static int registerCreator(int, Shape *(*CFuncptr)());
Shape* CreateObject(int);
private:
static std::map<int,Funcptr> & GetFactoryMap() {
static std::map<int,Funcptr> funcmap;
return funcmap;
}
};

和改变Factory::registerCreator对此:

int Factory::registerCreator(int ShapeID, Shape *(*CFuncptr)()) {   
GetFactoryMap()[ShapeID] = CFuncptr;
return 1;
}

这样 funcmap 将在第一次调用 registerCreator 时被初始化,并且永远不会在未初始化的情况下使用。

*或者,粗略地说,如果您不熟悉术语翻译单元,则使用不同的 .cpp 文件

关于c++ - 从静态成员函数访问静态映射 - 段错误 - C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8057682/

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