2010-09-29 45 views
7

Tôi đã nghe nói rằng việc sử dụng các đối tượng thành viên tĩnh không phải là một thực hành rất tốt.Điều gì là sai khi sử dụng một đối tượng thành viên tĩnh với một lớp?

Nói ví dụ, tôi có mã này:

class Foo { 
... 
static MyString str; 
}; 

Tôi định nghĩa và khởi tạo biến này trong các tập tin thực thi của lớp này như:

MyString Foo::str = "Some String"; // This is fine as my string API handles this. 

Khi tôi chạy mã này, tôi nhận được cảnh báo:

warning:'Foo::str' requires global construction. 

Tôi có khá nhiều thành viên như vậy trong lớp học, cách tốt nhất để xử lý thi S.

Cảm ơn,

Trả lời

10

Hầu hết các đối số chống lại chúng giống với các biến toàn cục:

  1. Thứ tự khởi tạo giữa các đơn vị biên dịch khác nhau là không xác định.
  2. Thứ tự khởi tạo bên trong một đơn vị biên dịch có thể ảnh hưởng đến hành vi — do đó có thể yêu cầu đặt hàng không nhỏ.
  3. Nếu một nhà xây dựng ném một ngoại lệ bạn không thể bắt được, chương trình của bạn sẽ bị chấm dứt.

PHỤ LỤC: Để xử lý đúng cách, bạn phải đảm bảo rằng các điểm trên không áp dụng cho mã của bạn và bỏ qua cảnh báo hoặc thiết kế lại chương trình của bạn: Bạn có thực sự cần chúng tĩnh không? Tại sao không sử dụng const char* Foo::str = "Some String";?

+0

Trong khi tôi đánh giá cao danh sách của bạn, đó là những chi tiết chủ yếu thực hiện.Từ quan điểm chức năng, điều này cũng ảnh hưởng đến sự tái sử dụng, và do đó các chương trình thử nghiệm và đa luồng. –

2

Sử dụng một thành viên tĩnh, bạn sẽ không đảm bảo an toàn thread, hãy tưởng tượng hai luồng cố gắng truy cập các thành viên tĩnh - bây giờ những gì sẽ là giá trị của thành viên đó - là nó trở thành một từ chủ đề x hoặc thread y, điều này cũng gây ra một tác dụng phụ, điều kiện chủng tộc, trong đó một chủ đề sửa đổi thành viên tĩnh trước khi chuỗi khác hoàn thành ... nói cách khác, sử dụng một thành viên tĩnh có thể nguy hiểm ...

+4

Đó là sự thật không chỉ cho các thành viên tĩnh mà còn cho bất kỳ dữ liệu được chia sẻ nào giữa các luồng. Tôi nghĩ rằng điều này không trả lời câu hỏi đúng như an toàn thread không có gì để làm với khởi tạo thành viên tĩnh. – ybungalobill

3

Lý do quan tâm lớn nhất với ví dụ này là việc xây dựng đối tượng thành viên tĩnh xảy ra trước main() và sự hủy diệt xảy ra sau main() (hoặc khi bạn gọi exit()). Cho đến nay, đó là một điều tốt. Nhưng khi bạn có nhiều đối tượng như thế này trong chương trình của bạn, bạn có nguy cơ bị lỗi khi mã cố gắng sử dụng một đối tượng chưa được xây dựng hoặc đã bị phá hủy.

Câu hỏi thường gặp về C++ Lite có some helpful discussion về chủ đề này, bao gồm giải pháp/giải pháp. Đọc được khuyến nghị là các câu hỏi từ 10.14 đến 10.18. 10.17 phù hợp nhất với ví dụ của bạn.

1

Ví dụ, cần phải biết số lượng phiên bản của một lớp. Điều này sẽ yêu cầu một thành viên tĩnh lớp để theo dõi số lượng các cá thể.

Không có gì sai khi có thành viên tĩnh của lớp nếu giải pháp vấn đề yêu cầu thiết kế như vậy. Nó chỉ là gritties nitty phải được chăm sóc như đã đề cập trong bài viết khác.

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