在头文件中执行const std :: string的正确方法?

时间:2012-04-18 02:15:33

标签: c++ static const stdstring

我正在编写一个Cocos2D-X游戏,其中玩家,敌人和其他角色将他们的属性存储在CCMutableDictionary中,这有点像std::map<std::string, CCObject*>的装饰者类。可以通过CCMutableDictionary::objectForKey(const std::string& key)方法访问字典中的值。

现在,在我的许多.cpp文件中包含的头文件中,我有一些const char * const字符串用于访问字典中的值,如下所示:

// in Constants.h
const char* const kAttributeX = "x";
const char* const kAttributeY = "y";

// in a .cpp file
CCObject* x = someDictionary->objectForKey(kAttributeX);

所以,如果我错了,请纠正我,但每次调用上述{{1}之一时,std::string的复制构造函数都会被调用并且临时std::string在堆栈中。使用objectForKey的方法,对吧?

如果是这样的话,我觉得如果那些常量属性键已经是const char* const个对象,那么它在运行时会更有效率。但是我如何以正确的方式做到这一点?

在Constants.h文件中定义它们,如下所示编译正常,但我觉得有些事情是不对的:

std::string

如果已经提出这个问题我很抱歉。我似乎无法在StackOverflow上找到我正在寻找的确切答案。

2 个答案:

答案 0 :(得分:22)

您编写的代码完全没问题,至少只有#include个{1}}文件只在一个源文件中。如果在多个源文件中使用头文件,则将多次定义相同的变量。在头文件中正确使用常量是将它们拆分为包含变量的声明的头(Constants.h)和包含变量的源文件(Constants.h)变量的定义

标题文件:

Constants.cpp

源文件:

#ifndef CONSTANTS_H
#define CONSTANTS_H

extern const std::string kAttributeX;
extern const std::string kAttributeY;

#endif

答案 1 :(得分:2)

您的第二个选项会导致在每个翻译单元(包含标题的cpp文件)中创建每个变量,这将略微增加代码大小以及添加一些运行时成本(在启动和销毁期间构造所有这些字符串)他们在流程终止期间)。

解决方案suggested by Joachim有效,但我发现分别声明和定义变量有点拖累。我个人讨厌重复自己,也不喜欢一遍又一遍地说同样的事情......

我不能在C ++中知道一个很好的解决方案,但是我所使用的编译器都支持__declspec( selectany )之类的东西,这样你就可以在头文件中定义变量了只获得一个实例化的对象(而不是每个翻译单元一个)。

__declspec( selectany ) extern const std::string kAttributeX = "x";

(为什么externconst都会看到this answer)。

您仍然有在流程启动期间支付所有全局变量的初始化价格的缺点。这可以在101%的时间内接受(给予或接受2%)但你可以通过使用惰性对象来避免这种情况(我written about something similar here)。