2010-01-29 35 views
11

Hãy nói rằng tôi có chương trình này:biến tĩnh trong phương pháp dụ

class Foo { 
public: 
    unsigned int bar() { 
     static unsigned int counter = 0; 
     return counter++; 
    } 
}; 

int main() 
{ 
    Foo a; 
    Foo b; 
} 

(Tất nhiên ví dụ này chẳng có ý nghĩa kể từ khi tôi muốn rõ ràng tuyên bố "counter" như một thuộc tính riêng, nhưng nó chỉ là để minh họa vấn đề).

Tôi muốn biết cách hoạt động của C++ trong loại tình huống này: liệu biến "truy cập" trong phương thức bar() có giống nhau cho mọi trường hợp không?

Trả lời

10

Có, counter sẽ được chia sẻ trên tất cả các trường hợp đối tượng thuộc loại Foo trong tệp thi hành của bạn. Miễn là bạn đang ở trong một môi trường đơn sơ, nó sẽ hoạt động như một bộ đếm dùng chung.

Trong môi trường đa luồng, bạn sẽ có các điều kiện cuộc đua thú vị để gỡ lỗi :).

+0

+1 để đề cập đến mối nguy hiểm trong môi trường đa luồng. – Omnifarious

+0

Giả sử trình biên dịch chưa xử lý điều đó cho bạn. Định nghĩa ngôn ngữ là biến là tính nhất quán trong tất cả các cuộc gọi đến phương thức. Vì vậy, nó là công việc biên dịch để thực thi điều này, vì vậy trong các ngôn ngữ đa luồng (phiên bản tiếp theo của C++) nó là công việc biên dịch. Trong phiên bản này, nó phụ thuộc vào sự tích hợp của trình biên dịch với thư viện luồng. gcc đã có bảo hiểm này và gurantees truy cập vào biến tĩnh là an toàn trên nhiều chủ đề. –

+0

@Martin York: tức là các biến tĩnh trong C++ 0x được đảm bảo là chuỗi địa phương? Thú vị thế nào, và nó có thể gây ngạc nhiên cho một số người. Giống như một truy cập ví dụ lớp tĩnh tốt đẹp. Đột nhiên, bạn sẽ được đếm các trường hợp cho mỗi chủ đề thay thế. Tôi không thể tin rằng họ sẽ thay đổi như thế. Bạn có chắc không?! – Omnifarious

2

Bởi "giống nhau cho mọi trường hợp", bạn có nghĩa là sẽ có một phiên bản của biến này được chia sẻ trên từng cá thể lớp, sau đó có, điều đó đúng. Tất cả các cá thể của lớp sẽ sử dụng cùng một cá thể biến đó.

Nhưng hãy nhớ rằng với các biến lớp, bạn phải thực hiện những việc như đa luồng trong nhiều trường hợp, đó là một chủ đề hoàn toàn khác.

1

Từ C++ Ngôn ngữ lập trình (2nd edition), trang 200, bởi Bjarne Stroustrup:

Không sử dụng tĩnh trừ bên trong [đơn giản] chức năng (§7.1.2) và các lớp học (§10.2.4).

+4

Quy tắc thật tuyệt vời. __BUT__ chỉ khi được sử dụng trong ngữ cảnh chính xác. Một người sử dụng nieve có thể lấy báo giá để hart. Nếu bạn đang đi để báo giá somthing như thế bạn __must__ bao gồm bối cảnh đầy đủ. –

0

Bạn chỉ cần nắm hai điều:

  1. biến tĩnh được lưu trữ trong khu vực tĩnh của chương trình thực hiện (đó là giống như của biến toàn cục).
  2. Phạm vi bị giới hạn bởi các quy tắc chung của dấu ngoặc đơn. Các biến tĩnh có liên quan có liên kết nội bộ.
+0

Đời không phải là cuộc đời của chương trình. Nó là từ lần sử dụng đầu tiên (có thể không bao giờ) cho đến khi hủy diệt (đó là thứ tự nghịch đảo của việc tạo ra các biến tĩnh). Khởi tạo ghi chú Alos là tốt vì nó là một phần của hàm không phải là lớp. –

+0

@niel .. xấu của tôi !! Tôi không thấy rằng – sud03r

+0

Câu cuối cùng là về các biến tĩnh phạm vi không gian tên. Các biến tĩnh cục bộ (như các biến trong câu hỏi) không có liên kết. (Không có cách nào để tham khảo các biến cục bộ từ các phạm vi khác nhau. Bạn sẽ tham khảo một biến được định nghĩa trong chính như thế nào? 'Main() :: v' không hoạt động, chẳng hạn). –

1

dụ của bạn là một vài dòng xa là một cái gì đó bạn có thể biên dịch và thử nghiệm:

#include <iostream> 
using namespace std; 
class Foo { 
public: 
    unsigned int bar() { 
     static unsigned int counter = 0; 
     return counter++; 
    } 
}; 

int main() 
{ 
    Foo a; 
    Foo b; 

    for (int i=0; i < 10; i++) 
     cout<<i<<". "<<a.bar()<<"/"<<b.bar()<<endl; 
} 

Kết quả trông như thế này:

0. 1/0 
1. 3/2 
2. 5/4 
3. 7/6 
4. 9/8 
5. 11/10 
6. 13/12 
7. 15/14 
8. 17/16 
9. 19/18 

Vì vậy, có, truy cập được chia sẻ trên tất cả các trường hợp.

+0

Điều thú vị là đầu ra của bạn là một ví dụ hoàn hảo về cách các điểm chuỗi và thứ tự thực hiện hoạt động và có thể dẫn đến kết quả phản trực giác. – Omnifarious

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