2009-08-25 33 views
7

Không thể liên kết sau hai tệp, khi tôi xóa từ khóa "tĩnh", thì không sao. Thử nghiệm với g ++. Kiểm tra với chính mình cho tệp đối tượng, thành viên tĩnh dường như được xuất dưới dạng biểu tượng đối tượng chung ... Tôi nghĩ rằng nó phải là một đối tượng cục bộ ...?nhiều định nghĩa cho thành viên tĩnh?

static1.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

static2.cpp

class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
void second() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 

Với thông tin lỗi:

/tmp/ccIdHsDm.o:(.bss+0x0): nhiều định nghĩa của `StaticClass :: a '

Trả lời

16

Có vẻ như bạn đang cố gắng có các lớp học địa phương trong mỗi tệp nguồn, có cùng tên. Trong C++, bạn có thể đóng gói các lớp địa phương trong một không gian tên vô danh:

namespace { 
class StaticClass 
{ 
public: 

    void setMemberA(int m) { a = m; } 
    int  getMemberA() const { return a; } 

private: 
    static int  a; 

}; 
int StaticClass::a = 0; 
} // close namespace 

void first() 
{ 
    StaticClass statc1; 
    static1.setMemberA(2); 
} 
+0

@Ropez: nó hoạt động tốt. Cảm ơn :) –

+0

Tôi cảm thấy xấu với tình trạng của công việc, vì câu trả lời của ropez dường như đã mang lại cho bạn giải pháp mà bạn đang tìm kiếm. cảm thấy tự do để di chuyển dấu kiểm đến một của mình :) 1 cho anh ta, anyway. –

+0

@Litb, cả hai bạn đều đúng :) bạn đã giải thích thêm. –

0

StaticClass cần một nơi để lưu trữ a, biến tĩnh sẽ được chia sẻ bởi tất cả các phiên bản lớp - có hai dòng làm như vậy, một dòng trong mỗi tệp. Việc xóa một tệp sẽ sửa lỗi liên kết.

9

Sau đây là định nghĩa của thành viên dữ liệu tĩnh. Nó phải xảy ra chỉ trong một tập tin được biên dịch và sau đó được liên kết.

int StaticClass::a = 0; 

Nếu bạn có nhiều định nghĩa như vậy, dường như bạn có nhiều chức năng được gọi là first. Họ sẽ đụng độ và người liên kết sẽ phàn nàn.

Tôi nghĩ rằng bạn đang nhầm lẫn các thành viên tĩnh với áp dụng tĩnh cho các biến phạm vi không gian tên. Ở mức không gian tên, static cho biến hoặc tham chiếu đến liên kết bên trong. Nhưng ở cấp độ phạm vi lớp (khi được áp dụng cho một thành viên), nó sẽ trở thành một thành viên tĩnh - một lớp được ràng buộc với lớp thay vì từng đối tượng riêng biệt. Điều đó sau đó không liên quan gì đến ý nghĩa của "tĩnh" nữa.

+0

Vấn đề là tôi nghĩ rằng các mối liên kết nên biết nó liên kết các biến trong tập tin đối tượng tại địa phương của mình, vì đây là một biến tĩnh địa phương, không phải là một tĩnh toàn cầu một. –

+0

không phải là địa phương hay toàn cầu. đó là một thành viên trong lớp. http://en.wikipedia.org/wiki/Class_variable –

+2

@arsane, Nếu bạn muốn có một lớp địa phương, bạn phải đặt nó vào một không gian tên ẩn danh.Khi bạn viết nó, StaticClass từ static1.cpp là cùng lớp với StaticClass từ static2.cpp. Trước khi nói rằng các lớp không được định nghĩa trong một tiêu đề, đừng quên rằng macropreprocessor làm việc bằng cách bao gồm văn bản. – AProgrammer

2

Tuyên bố

int StaticClass::a = 0; 

thực sự phân bổ lưu trữ cho các biến, đây là lý do tại sao nó nên chỉ viết một lần.

Đối với nhận xét của bạn, có thể bạn đang nhầm lẫn hai cách sử dụng khác nhau của từ khóa static. Trong C tĩnh được sử dụng để có nghĩa là "sử dụng liên kết nội bộ", điều này có nghĩa rằng tên của một biến hoặc chức năng sẽ không được nhìn thấy bên ngoài đơn vị dịch thuật mà nó được xác định.

Trong lớp học, static được sử dụng để xác định thành viên lớp học, đó là các biến hoặc phương pháp không đề cập đến một cá thể cụ thể của lớp. Trong trường hợp này lưu trữ cho một biến tĩnh phải được cấp phát một nơi nào đó (vì nó không phải là một phần của bất kỳ cá thể nào), nhưng chỉ ở một nơi tất nhiên.

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