1

我正在 Visual Studio 中进行 C++ 编码练习,并一直将此问题显示为标题。我知道问题发生在哪里,但我不知道为什么会发生以及如何解决它。请帮我解决一下这个。

类模板.h

typedef std::string QuestionName;
class ClassTemplete
{
public:
    ClassTemplete(Question iQuestionName);
private
    static std::map<QuestionName,ClassTemplete *> questionName_questionPointer_map_;
}

class_templete.cpp

map<QuestionName, ClassTemplete *> ClassTemplete::questionName_questionPointer_map_;

ClassTemplete::ClassTemplete(QuestionName iQuestionName)
{
    ClassTemplete::questionName_questionPointer_map_[iQuestionName] = this;
}

Chapter1_question1.h

class C1Q1 : public ClassTemplete
{
public:
    C1Q1(QuestionName iQuestionName) : ClassTemplete(iQuestionName) {};
private:
    static QuestionName question_name_;
    static C1Q1 question_instance_;
}

Chapter1_question1.cpp

QuestionName C1Q1::question_name_ = "C1Q1";
C1Q1 C1Q1::question_instance_(C1Q1::question_name_);

当我运行程序时,我发现这个问题发生在这个地方:

ClassTemplete::questionName_questionPointer_map_[iQuestionName] = this;

但是,我无法解释为什么会这样。

如果需要更多信息,请随时与我联系。

亲切的问候,

易记

4

2 回答 2

5

QuestionName C1Q1:::question_name_相对于什么位置ClassTemplate::questionName_questionPointer_map_?它们似乎都是具有静态存储持续时间的变量,即它们是在main()运行之前构建的。但是,C++ 编译器/链接器仅使用一个翻译单元(在这种情况下,对象从上到下构造)而不是在翻译单元之间(在这种情况下,对象以随机顺序构造)来命令构造此类全局对象。

你的问题看起来好像ClassTemplate::questionName_questionPointer_map会在C1Q1::question_name_. 也就是说,当C1Q1::question_name_被构造时,正在访问尚未构造的对象。

传统的解决方法是使static对象static依赖于其他对象,而是依赖于具有返回引用的局部变量的函数:

std::map<QuestionName,ClassTemplete *>&
ClassTemplete::questionName_questionPointer_map_() {
    static std::map<QuestionName,ClassTemplete *> rc;
    return rc;
}

(请注意,当您不使用 C++11 时,此构造不是线程安全的;使用 C++11 时它线程安全的)。

于 2013-11-02T23:14:36.510 回答
0

您必须使用,当您在地图中插入新键时std::map::insert,您不能这样做。ClassTemplete::questionName_questionPointer_map_[iQuestionName] = this;

此代码应该可以工作:

ClassTemplete::questionName_questionPointer_map_.insert(std::make_pair(iQuestionName, this));
于 2013-11-02T23:10:07.343 回答