2012-04-18 26 views
9

Tôi đang viết một trò chơi Cocos2D-X, nơi người chơi, kẻ thù và các nhân vật khác lưu trữ các thuộc tính của họ trong một CCMutableDictionary, đó là phần nào của một lớp trang trí cho std::map<std::string, CCObject*>. Một giá trị trong từ điển có thể được truy cập thông qua phương thức CCMutableDictionary::objectForKey(const std::string& key).Cách thích hợp để thực hiện const std :: chuỗi trong tệp tiêu đề?

Bây giờ, trong một tập tin header bao gồm nhiều file cpp của tôi, tôi đã có một vài const char * const dây để truy cập vào các giá trị trong từ điển, như thế này:

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

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

Vì vậy, chính xác cho tôi nếu tôi là sai, nhưng std::string của nhà xây dựng sao chép đang được gọi và tạm thời std::string là trên ngăn xếp mỗi khi tôi gọi một trong những phương pháp trên objectForKey sử dụng một const char* const, phải không?

Nếu vậy, tôi cảm thấy rằng sẽ hiệu quả hơn khi chạy nếu các khóa thuộc tính không đổi đó đã là std::string đối tượng. Nhưng làm cách nào để làm điều đó theo cách phải?

Xác định chúng trong Constants.h nộp như sau biên dịch tốt, nhưng tôi có một cảm giác rằng một cái gì đó chỉ là không đúng:

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

lời xin lỗi của tôi nếu câu hỏi này đã được hỏi. Tôi dường như không thể tìm thấy câu trả lời chính xác mà tôi đang tìm kiếm ở đây trên StackOverflow.

Trả lời

18

Mã bạn viết hoàn toàn ổn, ít nhất là bạn chỉ có #include tệp Constants.h trong chỉ một tệp nguồn. Nếu bạn sử dụng tệp tiêu đề trong nhiều tệp nguồn, bạn sẽ có cùng một biến được xác định nhiều lần. Việc sử dụng đúng các hằng số trong các tập tin tiêu đề là để tách chúng thành một tiêu đề (Constants.h) chứa tờ khai của các biến, và một tập tin nguồn (Constants.cpp) chứa định nghĩa của các biến:

Các phần đầu tập tin:

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

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

#endif 

các tập tin nguồn:

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

Vì vậy, nếu các chuỗi được xác định trong tệp .cpp, khi nào chúng thực sự được khởi tạo? –

+0

@NatWeiss Chúng sẽ được khởi tạo cùng với tất cả các biến toàn cục khác. –

+0

Vấn đề với các biến được xác định nhiều lần áp dụng khi chúng là "const char * const"? Tôi khá chắc chắn nó không, nhưng tôi không hiểu tại sao. Điều gì mang lại "const char * const" đặc quyền được định nghĩa ở một vị trí duy nhất bao gồm giá trị của nó (đẹp hơn nhiều, IMO, đặc biệt là về bảo trì)? – Brent212

2

tùy chọn thứ hai của bạn gây ra mỗi va các biến được tạo ra trong mọi đơn vị dịch (tệp cpp bao gồm tiêu đề) sẽ làm tăng kích thước mã cũng như thêm một chút chi phí thời gian chạy (xây dựng tất cả chuỗi đó trong khi khởi chạy và hủy chúng trong quá trình chấm dứt quá trình).

Giải pháp suggested by Joachim hoạt động nhưng tôi thấy việc khai báo và xác định các biến riêng rẽ là một chút kéo. Cá nhân tôi ghét lặp đi lặp lại bản thân mình, tôi cũng không muốn nói cùng một điều lặp đi lặp lại ...

Tôi không biết giải pháp nào tốt cho C++ nhưng trình biên dịch tôi đã làm việc với tất cả hỗ trợ một cái gì đó như __declspec(selectany) để bạn có thể xác định biến trong tệp tiêu đề và chỉ nhận được một đối tượng được khởi tạo (thay vì một đối tượng cho mỗi đơn vị dịch).

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

(Đối với lý do tại sao cả hai externconst thấy this answer).

Bạn vẫn có nhược điểm của việc trả giá khởi tạo của tất cả các biến toàn cầu trong quá trình khởi chạy quy trình. Điều này có thể chấp nhận được 101% thời gian (cho hoặc mất 2%) nhưng bạn có thể tránh điều này bằng cách sử dụng các đối tượng lười (tôi đã written about something similar here).

Các vấn đề liên quan