2010-09-08 70 views
14

Tôi muốn khai báo hằng số chuỗi sẽ được sử dụng trên nhiều lớp khác nhau trong dự án. Tôi đang xem xét hai phương ánhằng số chuỗi tĩnh trong lớp vs không gian tên cho hằng số [C++]

Lựa chọn 1:

#header file 
class constants{ 
    static const string const1; 
}; 

#cpp file 

const string constants::const1="blah"; 

Phương án 2:

#header file 
namespace constants{ 
    static const string const1="blah"; 
}; 

Chỉ cần tự hỏi điều gì sẽ là một thực hiện tốt hơn.

Đã nhìn

Where to store Class Specific named constants in C++

Where to put constant strings in C++: static class members or anonymous namespaces


UPDATE:

Lựa chọn 3:

Dựa trên các đề xuất từ ​​"potatoswatter" và "sellibitze" tôi hiện có triển khai sau đây?

#header file 
namespace constants{ 
    extern const string& const1(); //WORKS WITHOUT THE EXTERN ***WHY*** 
}; 

#cpp file 
namespace constants{ 
    const string& const1(){static string* str = new string ("blah"); return *str;} 
} 

Tôi bao gồm tệp tiêu đề mà tôi cần sử dụng hằng số. Có bất kỳ nhược điểm lớn nào của việc triển khai này không?

+0

Tùy chọn 2 dường như không phải là giải pháp. Các chuỗi vẫn sẽ được xác định riêng cho từng tệp nguồn, mặc dù xuất hiện trong cùng một không gian tên. – Potatoswatter

+4

Tùy chọn 2 là một giải pháp nếu Shishya thực sự nhận cú pháp cho nó đúng. (Không có 'tĩnh', và chuỗi chỉ có thể được khai báo trong tiêu đề, nhưng sẽ cần phải được định nghĩa trong tệp nguồn.) – pkh

+0

@pkh: cú pháp phức tạp hơn một chút so với điều đó; v) – Potatoswatter

Trả lời

9

Cập nhật 2 năm sau:

Mỗi toàn cầu truy cập bởi nhiều hơn một file nguồn nên được bọc trong một chức năng inline để cổ phần mối liên kết các đối tượng giữa các tập tin, và các chương trình khởi nó đúng cách.

inline std::string const &const1 { 
    static std::string ret = "hello, world!"; 
    return ret; 
} 

Chức năng inline là ngầm extern và có thể được bọc trong một namespace tên hoặc một lớp học, nếu bạn muốn. (Nhưng không sử dụng một lớp chỉ để giữ các thành viên tĩnh, vì các không gian tên tốt hơn cho điều đó. Và đừng sử dụng một không gian tên ẩn danh như vậy sẽ đánh bại mối liên kết, và mỗi nguồn sẽ thấy một đối tượng khác nhau std::string.)

+0

Nó sẽ sạch hơn khi có nhiều hằng số sử dụng hằng số không gian tên {...} trong tệp nguồn. – pkh

+0

@Potatoswatter: $ 2,13,4/2- Cho dù tất cả các chuỗi ký tự là khác biệt (có nghĩa là, được lưu trữ trong các đối tượng nonoverlapping) được implementationdefined. Hiệu quả của việc cố gắng sửa đổi một chuỗi ký tự là không xác định. Vì vậy, ngay cả khi chúng được xác định riêng biệt, chúng có thể không thực sự chiếm nhiều không gian riêng biệt trong bộ nhớ nếu đó là mối quan tâm. – Chubsdad

+0

@Chubsdad: Các chuỗi ký tự chuỗi duy nhất trong mã OP là bộ khởi tạo cho 'std :: string'. Tôi đã đề cập đến các đối tượng 'std :: string'. – Potatoswatter

4

Tùy chọn 1 đạt được giống như Tùy chọn 2, nhưng theo cách khác.

Nếu bạn định sử dụng một lớp chỉ có các thành viên tĩnh, đặc biệt là đối với truy cập/hằng số toàn cục, hãy sử dụng vùng tên.

4

Không. Tôi muốn đi với điều này:

// header file 
namespace constants { 
extern const char const1[]; 
} 

// cpp file 
namespace constants { 
extern const char const1[] = "blah"; 
} 

File header chứa một tuyên bố const1 với loại không đầy đủ nhưng mui trần để char const* và cpp-file chứa một định nghĩa của mảng nhân vật với mối liên hệ bên ngoài. Không có khởi tạo động như bạn có với std::string. Vì vậy, đó là một cộng, IMHO.

+0

Không phải mã trong tệp .cpp sẽ là mã này thay thế? 'const char hằng số :: const1 [] =" blah ";', nghĩa là: không có 'extern' và không có' không gian tên' redeclaration. –

+0

@Remy: * nhún vai *. Làm bất cứ việc gì bạn thích. Nhưng không có gì sai với mã tôi đăng. Bạn có thể xóa 'extern' trong tệp cpp nếu bạn bao gồm tiêu đề đã khai báo' const1' để có liên kết bên ngoài. Nhưng vì trong các biến cố định C++ ở phạm vi không gian tên có liên kết nội bộ theo mặc định, bạn cần phải có ít nhất một 'extern' trong đó. Những gì tôi đăng cũng hoạt động mà không bao gồm tiêu đề trong tệp cpp, btw. – sellibitze

7

Tất cả các câu trả lời đến khu nghỉ mát std::string đều có nguy cơ phân bổ động bộ nhớ cho chuỗi ký tự liên tục trong suốt thời gian tồn tại của chương trình (và nhị phân).

sellibitze câu trả lời đến gần nhưng nó có vấn đề tuyên bố nó một lần và sau đó xác định nó ở nơi khác, mà tôi không tìm thấy thanh lịch và là công việc nhiều hơn nữa. Cách tốt nhất là

namespace constants { 
    const char * const blah = "blah!" 
    const char * const yada = "yada yada!" 
} 

Đây là giải pháp được thảo luận thêm here.

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