2009-07-22 5 views
7

그래서 Qt 4.5를 배우기 시작했고 Signal/Slot 메커니즘이 도움이된다는 것을 알았습니다. 그러나 지금은 두 가지 유형의 아키텍처를 고려하고 있습니다. 신호/슬롯 대 직접 함수 호출

내가

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

class Updater 
{ 

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

주 사용하는 것입니다 : 간결 인라인 코드입니다.

신호와 지금

내가 할 수 단지

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

이, 청소기 인터페이스의 필요성을 줄일 수 있지만, 단지 내가 할 수 있기 때문에 나는 그것을해야합니까? 첫 번째 코드 블록은 더 많은 타이핑과 클래스를 필요로하지만 관계를 보여줍니다. 두 번째 코드 블록을 사용하면 모든 것이 "무형"입니다. 어느 것이 더 바람직하며, 경우에 따라 다를 경우 지침은 무엇입니까?

답변

9

신호를 내보내는 데는 몇 가지 스위치와 일부 추가 기능 호출 (연결되는 대상에 따라 다름)이 필요하지만 오버 헤드가 최소화되어야합니다.

신호 제공자는 클라이언트가 누구인지를 제어 할 수 없으며 실제로 모든 사람이 실제로 신호를 받았다고해도 반환합니다.

이것은 매우 편리하며 완전한 디커플링을 허용하지만 실행 순서가 중요하거나 반환 할 때 문제가 발생할 수 있습니다.

당신이하고있는 일을 정확히 알지 못한다면, 임시 데이터에 대한 포인터를 넘겨서는 안됩니다. 필요한 경우 회원 변수의 주소를 전달하십시오. Qt는 객체의 모든 이벤트가 처리 될 때까지 객체의 삭제를 지연시키는 방법을 제공합니다.

신호가 이벤트 루프를 실행해야 할 수도 있습니다 (직접 연결하지 않는 한).

전반적으로 이벤트 구동 형 응용 프로그램에서는 많은 의미가 있습니다 (실제로는 응용 프로그램이 없으면 빠르게 매우 성가 시게됩니다).

이미 프로젝트에서 Qt를 사용하고 있다면 확실히 사용하십시오. Qt에 대한 의존성이 받아 들여지지 않는다면, 부스트는 비슷한 메커니즘을 가지고 있습니다.

3

다른 차이점이 있습니다. # 1은 IDataBlock 인터페이스에 하드 결합되어 있으며 Updater 클래스는 "someblock"에 대해 알아야합니다. # 2는 연결 호출 (또는 연결 해제를 포함한 여러 연결)을 통해 지연 연결될 수 있으므로보다 동적 인 접근이 가능합니다. # 2는 메시지 (Smalltalk/ObjC를 생각해보십시오.)가 아닌 호출 (C/C++을 생각하십시오)과 같은 역할을합니다. 메시지는 여러 번 발송 될 수도 있습니다. # 1에서 해당 기능을 구현해야합니다.

코드 성능이나 즉각적인 반환 데이터의 필요성으로 인해 (또는 Qt에 대한 의존성이 바람직하지 않은 경우가 아니라면) 융통성으로 인해 신호/슬롯을 사용하는 것이 좋습니다.

2

두 양식이 비슷한 것처럼 보일 수 있습니다. 기능적으로 그것은 사실입니다. 실제로는 더 큰 문제를 해결하고 있습니다. 이러한 경우 외부 상황으로 인해이 두 가지 해결책이 동등하지 않을 수 있습니다.

일반적인 경우는 소스와 싱크 사이의 관계를 알아내는 것입니다. 그들은 심지어 서로를 알고 있습니까? 첫 번째 예에서는 updateData()가 싱크를 전달해야합니다. 그러나 트리거가 GUI 버튼 [데이터 업데이트]이면 어떻게됩니까? 푸시 버튼은 일반적인 구성 요소이므로 IDataBlock에 대해 알면 안됩니다.

해결 방법은 물론 m_someblock 멤버를 Updater에 추가하는 것입니다. 푸시 버튼은 이제 Updater에있는 멤버를 업데이트합니다. 그러나 이것은 정말로 당신이 의도 한 것입니까?