2014-05-04 16 views
6

Tôi phát hiện ra khởi tạo đồng bộ một vài ngày trước, và tôi thấy ở khắp mọi nơi mà mọi người nên sử dụng nó càng nhiều càng tốt.Không sử dụng khởi tạo thống nhất có nguy hiểm không?

Tuy nhiên, tôi không thể không nghĩ rằng cú pháp mới này là rắc rối hơn nó có giá trị ...


dụ đầu tiên

Giả sử tôi viết một thư viện, trong đó tôi có cấu trúc như sau:

struct MyStruct 
{ 
    int member0; 
    int member1; 
} 

Người dùng có thể viết thứ gì đó như thế này bằng cách sử dụng tổng hợp khởi tạo:

MyStruct myVar = {0, 1}; // member0 = 0 and member1 = 1 

Bây giờ, chúng ta hãy nói rằng tôi cập nhật thư viện của tôi, và rằng các struct bây giờ trông như thế này:

struct MyStruct 
{ 
    int member0; 
    int member1; 

    MyStruct(int p0, int p1) : member0(p1), member1(p0){} 
} 

Trước khi C++ 11, mã người sử dụng sẽ ngừng biên soạn, trong đó sẽ buộc người dùng viết lại mã của mình và sử dụng hàm tạo. Nhưng bây giờ, mã sẽ biên dịch và được hiểu là thống nhất khởi:

MyStruct myVar = {0, 1}; // member0 = 1 and member1 = 0 

Nếu không có người sử dụng biết, cập nhật thư viện của ông sẽ làm cho mã của mình làm điều gì đó rất khác nhau!


dụ thứ hai

Bây giờ, chúng ta hãy nói rằng tôi có một lớp học như thế này trong thư viện của tôi:

class MyClass 
{ 
public: 
    MyClass(int size, int default = 0) : elements(size, default){} 
private: 
    std::vector<int> elements; 
} 

Người dùng có thể sử dụng nó như thế này:

MyClass myVar (3,1); // 3 elements with value 1 

hoặc, sử dụng đồng bộ hóa bắt đầu, như sau:

MyClass myVar {3,1}; // 3 elements with value 1 

Sau đó, một lần nữa, hãy nói rằng tôi cập nhật thư viện của mình. Lớp bây giờ nhìn như thế này:

class MyClass 
{ 
public: 
    MyClass(int size, int default = 0) : elements(size, default){} 
    MyClass(std::initializer_list<int> elts) : elements(elts){} 
private: 
    std::vector<int> elements; 
} 

Sẽ không có một vấn đề nếu một constructor cổ điển được sử dụng:

MyClass myVar (3,1); // 3 elements with value 1 

nhưng việc giải thích mã sẽ thay đổi nếu khởi tạo thống nhất được gọi là:


Dựa trên những ví dụ này, có vẻ như tôi cực kỳ nguy hiểm đối với người dùng đối với chúng tôi e khởi tạo đồng bộ, vì việc giải thích mã có thể thay đổi khi mọi thứ được thêm vào các thư viện được sử dụng, mà không có bất kỳ cảnh báo nào.

Tệ hơn nữa, việc giới thiệu khởi chạy đồng bộ làm cho việc khởi tạo tổng hợp trở nên nguy hiểm.

Tôi đã bỏ lỡ điều gì chưa? Có một ngữ cảnh trong đó việc sử dụng đồng bộ hóa khởi tạo vừa an toàn vừa hữu ích?

+2

+1 Khá điểm thú vị. Đối với trường hợp thứ hai, cú pháp là tương tự trong cả hai trường hợp, nhưng vẫn còn một sự khác biệt. Nhưng đối với trường hợp đầu tiên, trông hoàn toàn phiền hà. – Rubens

+6

Tôi nghĩ rằng việc thay đổi giao diện là nguy hiểm bất kể khởi tạo đồng bộ có liên quan hay không. – bolov

Trả lời

6

Tôi nghĩ rằng cả hai vấn đề bạn giải quyết đều có rất ít việc phải thực hiện với việc khởi chạy đồng bộ, nhưng minh họa sự nguy hiểm của việc thay đổi giao diện.

Bạn có thể lưu trữ các thay đổi tối ưu rất giống nhau trong mã người dùng bằng cách cập nhật thư viện của bạn như thế này:

struct MyStruct 
{ 
    int member1; 
    int member0; 
} 

Không khởi thống nhất involed. Đây cũng là có thể, trước C++ 11, để thay đổi các nhà xây dựng được lựa chọn bởi độ phân giải quá tải:

class some_class 
{ 
    public: 
    some_class(int); 
} 

tài coder:

some_class var(1.0); 

Nếu mã đã được thay đổi để:

class some_class 
{ 
    public: 
    some_class(int); 
    some_class(double); 
} 

Phương thức khởi tạo thứ hai sẽ được gọi. Một lần nữa, không có khởi tạo đồng bộ, nhưng cùng một vấn đề xảy ra. Vì vậy, trong khi cả hai ví dụ đều cho thấy ý nghĩa của mã người dùng có thể thay đổi bằng giao diện thư viện, đây không phải là vấn đề xâm nhập hoặc cụ thể để khởi tạo thống nhất mà là thiết kế tối ưu. Nó chỉ minh họa một thực tế là một giao diện thư viện nên được thiết kế rất cẩn thận.

Trên sự phản đối, khởi tạo đồng bộ cung cấp một số lợi thế thực sự. Đối với những người này, hãy xem điều này excellent answer

+0

Bạn có một điểm. Nhưng sau đó tôi cho rằng điều đó có nghĩa là purists sẽ không sử dụng khởi tạo thống nhất nhiều ... – Eternal

+0

Purists thường không sử dụng bất cứ điều gì bởi vì nó nguy hiểm. Họ không thiết kế giao diện bởi vì họ có thể thay đổi, v.v ... – Nicolas

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