2012-04-18 104 views
9

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

,通过我的很多.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); 

所以,如果指正我错了,但是std::string的拷贝构造函数正在被调用,并且每当我使用const char* const调用上述objectForKey方法中的一个时,临时std::string就在堆栈上,对吧?

如果是这样,我觉得如果这些常量属性键已经是std::string对象,那么运行效率会更高。但我该怎么做,权利的方式?

定义他们在Constants.h文件中像下面编译罚款,但我有一种感觉,有些事情是不正确的:

// in Constants.h 
const std::string kAttributeX = "x"; 
const std::string kAttributeY = "y"; 

我的道歉,如果这个问题已经问。我似乎无法找到我在StackOverflow上寻找的确切答案。

回答

18

你写的代码非常好,至少你只有一个源文件中只有#includeConstants.h文件。如果您在多个源文件中使用头文件,则会多次定义相同的变量。正确的使用头文件中的常量是他们分成含有声明的变量头(Constants.h),和源文件(Constants.cpp),其中包含定义的变量

的头文件:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

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

#endif 

源文件:

const std::string kAttributeX = "x"; 
const std::string kAttributeY = "y"; 
+0

因此,如果字符串是在.cpp文件中定义的,它们何时实际实例化? – 2012-04-18 03:39:04

+0

@NatWeiss它们将与所有其他全局变量一起实例化。 – 2012-04-18 18:26:34

+0

多次定义的变量问题是否适用于“const char * const”?我很确定它没有,但我不明白为什么。是什么赋予“const char * const”在单个位置定义的特权,包括其值(更好,IMO,特别是维护方面)? – Brent212 2015-02-06 23:09:47

2

你的第二个选项使各Va的可以在每个翻译单元(包含头文件的cpp文件)中创建riables,这会稍微增加代码大小并增加一些运行时成本(在启动期间构建所有字符串,并在进程终止期间销毁它们)。

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

我不知道在C++本身中有一个很好的解决方案,但是我所使用的编译器都是支持类似于__declspec(selectany)的东西,以便您可以在头文件中定义变量,并且仅实例化一个对象(而不是每个翻译单元一个)。

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

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

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

相关问题