2009-07-22 22 views
7

Vì vậy, tôi đã bắt đầu tìm hiểu Qt 4.5 và tìm thấy cơ chế Signal/Slot để được trợ giúp. Tuy nhiên, bây giờ tôi thấy mình đang xem xét hai loại kiến ​​trúc.Tín hiệu/Slot so với các cuộc gọi hàm trực tiếp

Đây là một trong những Tôi sẽ sử dụng

class IDataBlock 
{ 
    public: 
    virtual void updateBlock(std::string& someData) = 0; 
} 

class Updater 
{ 

    private: 
    void updateData(IDataBlock &someblock) 
    { 
     .... 
     someblock.updateBlock(data); 
      .... 
    } 
} 

Lưu ý: Mã inlined cho ngắn gọn.

Bây giờ với tín hiệu tôi có thể chỉ

void Updater::updateData() 
{ 
    ... 
    emit updatedData(data); 
} 

Đây là sạch hơn, giảm sự cần thiết của một giao diện, nhưng tôi nên làm điều đó chỉ vì tôi có thể? Khối mã đầu tiên yêu cầu nhập nhiều hơn và nhiều lớp hơn, nhưng nó cho thấy một mối quan hệ. Với khối mã thứ hai, mọi thứ trở nên "vô dụng" hơn. Cái nào là hấp dẫn hơn, và nếu nó là cơ sở từng trường hợp, các hướng dẫn là gì?

Trả lời

9

Phát tín hiệu sẽ tốn ít công tắc và một số cuộc gọi chức năng bổ sung (tùy thuộc vào cách thức và cách thức được kết nối), nhưng chi phí tối thiểu phải nhỏ.

Nhà cung cấp tín hiệu không kiểm soát được khách hàng của mình là ai và ngay cả khi họ thực sự nhận được tín hiệu vào thời điểm phát ra trả lại.

Điều này rất thuận tiện và cho phép tách hoàn toàn, nhưng cũng có thể dẫn đến các vấn đề khi đặt hàng các vấn đề thực hiện hoặc khi bạn muốn trả lại một cái gì đó.

Không bao giờ chuyển con trỏ tới dữ liệu tạm thời (trừ khi bạn biết chính xác mình đang làm gì và thậm chí sau đó ...). Nếu bạn phải, vượt qua địa chỉ của biến thành viên của bạn - Qt cung cấp một cách để trì hoãn việc phá hủy đối tượng cho đến khi tất cả các sự kiện cho nó được xử lý.

Tín hiệu cũng có thể requre vòng lặp sự kiện sẽ được chạy (trừ khi kết nối trực tiếp tôi nghĩ).

Nhìn chung, chúng tạo ra rất nhiều ý nghĩa trong các ứng dụng hướng sự kiện (thực sự nó nhanh chóng trở nên rất khó chịu mà không có chúng).

Nếu bạn đã sử dụng Qt trong một dự án, hãy sử dụng chúng một cách chắc chắn. Nếu phụ thuộc vào Qt là không thể chấp nhận được, thì boost có một cơ chế tương tự.

3

Có một điểm khác biệt. # 1 là khó kết hợp với giao diện IDataBlock, và lớp Updater cần biết về "someblock". # 2 có thể được kết nối muộn thông qua một cuộc gọi kết nối (hoặc một số, bao gồm cả ngắt kết nối), dẫn đến một cách tiếp cận năng động hơn. # 2 hoạt động giống như một tin nhắn (nghĩ Smalltalk/ObjC) và không phải là một cuộc gọi (nghĩ C/C++). Tin nhắn cũng có thể phải chịu nhiều công văn, yêu cầu thực hiện tính năng đó bằng tay trong # 1.

Sở thích của tôi là sử dụng tín hiệu/khe do tính linh hoạt, trừ khi hiệu suất mã hoặc nhu cầu trả lại dữ liệu ngay lập tức không cho phép (hoặc sự phụ thuộc vào Qt không được mong muốn).

2

Hai biểu mẫu có thể giống nhau. Chức năng, đó là sự thật. Trong thực tế, bạn đang giải quyết một vấn đề lớn hơn. Trong những trường hợp đó, hoàn cảnh bên ngoài sẽ khiến hai giải pháp này không tương đương nhau.

Trường hợp thông thường là tìm ra mối quan hệ giữa nguồn và bồn rửa. Họ có biết nhau không? Trong ví dụ đầu tiên của bạn, updateData() cần phải có sink được truyền vào. Nhưng nếu trigger là một nút GUI [Update Data] thì sao? Các nút bấm là các thành phần chung và không nên biết về IDataBlock.

Một giải pháp là tất nhiên để thêm thành viên m_someblock vào Trình cập nhật. Các nút bấm bây giờ sẽ cập nhật bất cứ thành viên là trong Updater. Nhưng đây thực sự là những gì bạn dự định?

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