Qt“비공개 슬롯 :”이것은 무엇입니까?


82

나는 그것을 사용하는 방법을 이해하지만 그것의 구문은 나를 괴롭힌다. "비공개 슬롯 :"이란 무엇입니까?

전에 클래스 정의에서 private 키워드와 : 사이에 무언가를 본 적이 없습니다. 여기에 멋진 C ++ 마법이 있습니까?

그리고 여기에 예 :

 #include <QObject>

 class Counter : public QObject
 {
     Q_OBJECT

 public:
     Counter() { m_value = 0; }

     int value() const { return m_value; }

 public slots:
     void setValue(int value);

 ...

3
이것은 표준 C ++가 아닙니다. 이것은 QT 프레임 워크 구조입니다. QT 신호 및 슬롯을 조회 합니다 .
Alok 저장

1
C로 컴파일 할 때 ++ slots로 정의된다 #define slots. Qt MOC를 사용하여 컴파일 할 때 C ++ 컴파일러 용 코드를 생성합니다.
dalle

2
lol 이것은 내가 C ++를 너무 오랫동안 사용하지 않았기 때문에 이해하기 더 어려웠습니다. 나는 그들이 새로운 것을 추가했다고 생각했습니다
dtc

답변:


56

슬롯은 C ++의 Qt 특정 확장입니다. Qt의 전처리 기인 MOC (Meta-Object Compiler)를 통해 코드를 전송 한 후에 만 ​​컴파일됩니다. 설명서는 http://doc.qt.io/qt-5/moc.html 을 참조 하십시오 .

편집 : Frank가 지적했듯이 moc는 연결에만 필요합니다. 추가 키워드는 표준 전처리기로 # 정의됩니다.


고마워요, Qt의 전처리 기는 무슨 일이 일어나고 있는지에 대한 내 정신 모델에서 제가 놓친 것입니다.
Justin

16
정확하지 않은 경우, "신호"와 "슬롯"이 비어있는 정의이므로 컴파일러에서 볼 수 없으므로 코드는 항상 컴파일됩니다. 이러한 매크로는 추가 코드 를 생성하는 moc에 대한 힌트입니다 . 원본 .h 및 .cpp 파일은 변경되지 않고 moc없이 잘 컴파일됩니다. moc 생성 정의 (신호 정의, 메타 오브젝트 등)가 그렇지 않으면 누락되므로 실패 할 수있는 것은 연결입니다.
Frank Osterfeld 2012

1
는 IS slots키워드가 필요? slots키워드 없이 슬롯을 호출하는 몇 가지 작은 Qt 프로그램을 컴파일 / 링크하려고 시도 했으며 잘 구축되었습니다. 내 실험은 다음을 보여줍니다 : signals:확실히 필요하고, slots불필요 할 수 있으며, emit다른 곳에서 읽은 것처럼 불필요한 것 같습니다.
It 's Your App LLC

1
slotsQt5에서는 필요하지 않습니다. Qt connect()는 신호를 람다를 포함한 임의의 함수에 연결할 수 있도록 구문을 업데이트했습니다 . 이 때문에 slots필요하지 않습니다. 그러나 slots키워드는 객체 QMetaObject가 작성 되는 방식에 여전히 영향을 미칩니다 . moc(일명 "메타 객체 컴파일러")는 메서드 slots:가 클래스 정의 섹션 내에 있지 않으면 메서드를 슬롯으로 인식하지 않습니다 . 따라서 연결은 계속 작동하지만 메서드는 내부 검사 도구에 표시되지 않습니다.
Chris

19

같은 키워드는 public, privateQt는 슬롯 무시됩니다. 모든 슬롯은 실제로 공용이며 연결할 수 있습니다.


30
메서드가 신호 / 슬롯 메커니즘을 통해 호출 될 때 액세스 지정자는 무시됩니다. 그러나 슬롯은 "일반적인"방법이기도합니다. 전통적인 방법을 사용하여 호출 할 때 액세스 지정자가 고려됩니다.
borges 2012

4
@borges 및 미래의 독자. Qt5에서 connect () 메서드는 함수 포인터를 사용할 수 있습니다. 함수 포인터로 연결하면 액세스 지정자가 신호 / 슬롯 메커니즘에 적용됩니다.
Tod

3
@borges 이것이 잘못되었거나 적어도 설명이 명확하지 않다고 생각합니다. 액세스 지정자는 신호를 슬롯에 연결하는 기능을 제한하지 않습니다. 즉, 개인 슬롯은 모든 신호에 연결할 수 있습니다 . 그러나 액세스 지정자는 호출되는 동안 클래스에서 멤버 함수를 (일반적인 방식으로) 보호합니다. 따라서 액세스 지정자는 신호 / 슬롯 메커니즘을 통해 호출 될 때 "무시"되지 않습니다. 슬롯을 신호에 연결하는 것과 관련이 없지만 this우리가 익숙한 방식으로 기능을 보호합니다 .
그것은 당신의 앱 LLC의

4

슬롯을 비공개로 선언하면 다른 방법과 마찬가지로 비공개 인 컨텍스트에서 슬롯을 참조 할 수 없습니다. 결과적으로 개인 슬롯 주소를 전달할 수 없습니다.connect .

신호를 private으로 선언하면이 클래스 만 관리 할 수 ​​있지만 함수 멤버 포인터에는 액세스 제한이 없음을 의미합니다 .

class A{
    private:
    void e(){

    }
    public:
    auto getPointer(){
        return &A::e;   
    }
};

int main()
{
    A a;
    auto P=a.getPointer();
    (a.*P)();
}

그 외에는 어떤 다른 답변 언급하는 것은 유효 너무 :
- 당신은 여전히 트릭 외부에서 개인 신호와 슬롯을 연결할 수 있습니다
- signalsslots빈 매크로하고 언어 표준을 아프게하지 않습니다


이 질문에 찬성표가없는 이유는 무엇입니까? 문제가 있습니까? slots매크로가 도움이되는 진술을 찾았습니다 . connect트릭 없이는 개인 슬롯 기능 포인터를 연결할 수 없습니다 .
Arch Linux Tux

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.