알쓸전컴(알아두면 쓸모있는 전자 컴퓨터)

Q_D Q_Q 에 대해서 본문

QT/Qt Multimedia 공부하기

Q_D Q_Q 에 대해서

백곳 2017. 9. 11. 19:43

Q_D

qt 오픈 소스를 보면 해당 내용이 아주 많이 나옵니다. 

#define Q_D(Class) Class##Private * const d = d_func()
#define Q_Q(Class) Class * const q = q_func()


로 정의 되어 있습니다. 


이것이 무엇에 사용 되는지 알아 보겠습니다. 


Qt에서는 이것을 d-pointer 라고 부릅니다. 


사용되는것은 자신의 privete 클래스에 접근 하기 위해서 입니다. 


외부에서 라이브러리를 사용할때 일반적으로 private 클래스에는 접근 하지 못하도록 합니다. 


예를 들면 

widget.h

 class WidgetPrivate;
 
 class Widget
 {
     // ...
     Rect geometry() const;
     // ... 
 
 private:
     WidgetPrivate *d_ptr;
 };

widget_p.h

/* widget_p.h (_p means private) */
struct WidgetPrivate
{
    Rect geometry;
    String stylesheet;
};

widget.cpp

// With this #include, we can access WidgetPrivate.
#include "widget_p.h"

Widget::Widget() : d_ptr(new WidgetPrivate)
{
    // Creation of private data
}

Rect Widget::geometry() const
{
    // The d-ptr is only accessed in the library code
    return d_ptr->geometry;
}

label.h

class Label : public Widget
{
    // ...
    String text();

private:
    // Each class maintains its own d-pointer
    LabelPrivate *d_ptr;
};

label.cpp

struct LabelPrivate
{
    String text;
};

Label::Label() : d_ptr(new LabelPrivate)
{
}

String Label::text()
{
    return d_ptr->text;
}


이런식으로 클래스가 정의 되는데 


결국에는 private 로 d_ptr 에 넣어준 포인터를 


Q_D 를 통해서 가져 오게 됩니다. 


위의 예제에서는 부모(Widget) 에서 정의된 d_ptr 을 자식들이 상속 받에 되고 결국에에 Label 에서 


d_ptr에 new LabelPrivate 가 들어 가게 됩니다.  


결국에 Q_D(Lebel) 은 new LabelPrivate의 주소값을 가져오게 됩니다. 



Q_Q


q-pointer 라고 불리며 Private 클래스에서 부모 클래스에 접근 하기 위해서 사용 됩니다. 


widget_p.h

struct WidgetPrivate
{
    // Constructor that initializes the q-ptr
    WidgetPrivate(Widget *q) : q_ptr(q) { }
    Widget *q_ptr; // q-ptr points to the API class
    Rect geometry;
    String stylesheet;
};

widget.cpp

#include "widget_p.h"
// Create private data.
// Pass the 'this' pointer to initialize the q-ptr
Widget::Widget() : d_ptr(new WidgetPrivate(this))
{
}

Rect Widget::geometry() const
{
    // the d-ptr is only accessed in the library code
    return d_ptr->geometry;
}

Next, another class based on Widget.

label.h

class Label : public Widget
{
    // ...
    String text() const;

private:
    LabelPrivate *d_ptr;
};

label.cpp

// Unlike WidgetPrivate, the author decided LabelPrivate
// to be defined in the source file itself
struct LabelPrivate
{
    LabelPrivate(Label *q) : q_ptr(q) { }
    Label *q_ptr;
    String text;
};

Label::Label() : d_ptr(new LabelPrivate(this))
{
}

String Label::text()
{
    return d_ptr->text;
}


Q_D 와 비슷한 의미로  


d_ptr(new LabelPrivate(this)) 를 사용 하며  this 로 현재 Label의 주소값을넘겨 주면서 q_ptr 을 설정해 줍니다. 


Q_Q(Label) 은 q_ptr 에 저장된 값을 가져오게 되는것입니다. 



Comments