2011-09-27 75 views
11

thể trùng lặp:
C++ static constant string (class member)
static const C++ class member initialized gives a duplicate symbol error when linkingLàm cách nào để xác định hằng số chuỗi trong C++?

Kinh nghiệm của tôi với C++ trước ngày việc bổ sung các lớp chuỗi, vì vậy tôi bắt đầu lại trong một số cách khác nhau.

Tôi đang xác định tệp tiêu đề cho lớp của mình và muốn tạo hằng số tĩnh cho url. Tôi đang cố gắng thực hiện điều này bằng cách thực hiện như sau:

#include <string> 
class MainController{ 
private: 
    static const std::string SOME_URL; 
} 

const std::string MainController::SOME_URL = "www.google.com"; 

Nhưng điều này cho tôi một định nghĩa trùng lặp trong liên kết.

Tôi làm cách nào để thực hiện việc này?

+0

dup http://stackoverflow.com/questions/2888805/static-const-c-class-member-initialized-gives-a-duplicate-symbol-error-when-lin –

Trả lời

10

Di chuyển

const std::string MainController::SOME_URL = "www.google.com"; 

vào một tập tin cpp. Nếu bạn có nó trong một tiêu đề, sau đó mỗi .cpp bao gồm nó sẽ có một bản sao và bạn sẽ nhận được lỗi biểu tượng trùng lặp trong liên kết.

+1

Tôi đoán những gì tôi không hoàn toàn hiểu được rằng tôi có những điều này trong các vệ sĩ tiêu đề của tôi. Điều này đã khắc phục được sự cố, tôi không hiểu tại sao ... – Thom

+3

@Có, vấn đề không được giải quyết với các tiêu đề bảo vệ vì mỗi đơn vị dịch (tệp cpp) bao gồm tiêu đề để mỗi đơn vị dịch kết thúc bằng một 'bản sao' của chuỗi có cùng tên, kết quả là mỗi đơn vị dịch được biên dịch chính xác. Tuy nhiên, khi liên kết nhiều đơn vị dịch có cùng biểu tượng (chuỗi) và kích hoạt lỗi liên kết do liên kết tượng trưng. –

2

Bạn nên đặt định nghĩa const std::string MainController::SOME_URL = "www.google.com"; vào một tệp nguồn duy nhất, không có trong tiêu đề.

2

Xác định lớp trong file header:

//file.h 
class MainController{ 
private: 
    static const std::string SOME_URL; 
} 

Và sau đó, trong tập tin nguồn:

//file.cpp 
#include "file.h" 

const std::string MainController::SOME_URL = "www.google.com"; 
9

Bạn cần phải đặt dòng

const std::string MainController::SOME_URL = "www.google.com"; 

trong file cpp , không phải tiêu đề, vì số one-definition rule. Và thực tế là bạn không thể trực tiếp khởi tạo nó trong lớp là vì std::string không phải là một loại không thể thiếu (như int).

Cách khác, tùy thuộc vào trường hợp sử dụng của bạn, bạn có thể xem xét không tạo thành viên tĩnh nhưng thay vào đó sử dụng một không gian tên ẩn danh. See this post for pro/cons.

+0

Ngay cả khi đó là loại tích phân, nó sẽ đưa ra lỗi. Tức là, nó KHÔNG có gì để làm với * type * của thành viên tĩnh; miễn là bạn cung cấp * định nghĩa * của thành viên trong tiêu đề, nó sẽ đưa ra lỗi. – Nawaz

+1

@Nawaz Trong thực tế. Chính thức, nhiều định nghĩa trong các đơn vị dịch thuật khác nhau là hành vi không xác định, do đó, một trình biên dịch có thể làm cho nó hoạt động. (Hoặc làm bất cứ điều gì khác, nhưng "làm cho nó hoạt động" là một thực hiện phổ biến trong C. Trường hợp nhà thầu đã không nhập vào nó.) –

+1

@ JamesKanze: Bạn đang cố gắng để nói gì? Rằng nó phải làm với * type * của thành viên tĩnh? – Nawaz

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