Russian Qt Forum
Ноябрь 26, 2024, 02:30 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Что есть d_func(), d, q и зачем оно нужно и как с этим быть?!  (Прочитано 8908 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« : Август 16, 2009, 16:38 »

Доброго дня!

Собственно сабж по теме..

Я тут принялся исходники QAbstractSocket изучать для того, чтобы на его основе написать свой класс для работы с последовательным устройством и я запнулся на преобразованиях типа d_func() , d, q и т.п... В принципе я понял суть d и q (поверхностно), а вот с d_func() ума не приложу как разбираться... т.е я уже запутался...
Меня интересует вопрос, почему тролли в классе  QAbstractSocketEngine во многих функциях (см. qabstractsocketengine.cpp) используют так:
Код:
...
QAbstractSocket::SocketState QAbstractSocketEngine::state() const
{
    return d_func()->socketState;
}

void QAbstractSocketEngine::setState(QAbstractSocket::SocketState state)
{
    d_func()->socketState = state;
}
...

Вопрос: почему они не делают через d !!!???  например типа :
Код:
...
QAbstractSocket::SocketState QAbstractSocketEngine::state() const
{
    Q_D(const QAbstractSocketEngine);
    return d->socketState;
}

void QAbstractSocketEngine::setState(QAbstractSocket::SocketState state)
{
    Q_D(const QAbstractSocketEngine);
    d->socketState = state;
}
...
И вообще: когда нужно применять d_func() а когда d ? И т.п. ?
Записан

ArchLinux x86_64 / Win10 64 bit
Rcus
Гость
« Ответ #1 : Август 16, 2009, 17:25 »

макрос Q_D раскрывается в объявление переменной d и инициализацию через d_func(), d_func просто обертка вокруг reinterpret_cast для d_ptr, что упрощает работу с параллельными иерархиями QObject/QObjectPrivate. Разница только в том личных представлениях об удобстве, а поскольку троллей более одного то и пишут они по-разному (самый яркий пример я нашел когда изучал нестабильность динамической сортировки в qsortfilterproxymodel.cpp - вся приватная часть написана в snake style).

А насчет вопроса что с этим делать... Именно с этими указателями ничего, http://techbase.kde.org/Policies/Library_Code_Policy#D-Pointers отвечает на вопрос как построить свою иерархию подобным образом. А вообще это все реализация [GoF,Bridge].
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #2 : Август 16, 2009, 17:47 »

1. так я не понял все-таки... зачем делать d_func() в примерах, которые я выше привел нельзя ли это же сделать через d?
2. и еще зачем в протектед секцию добавляют еще один QAbstractSocket :
Код:
class Q_NETWORK_EXPORT QAbstractSocket : public QIODevice
{
    Q_OBJECT
public:
...
    QAbstractSocket(SocketType socketType, QObject *parent);
...
protected:
...
    QAbstractSocket(SocketType socketType, QAbstractSocketPrivate &dd, QObject *parent = 0);
...

}

это может быть связано с d_func() ?
Записан

ArchLinux x86_64 / Win10 64 bit
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #3 : Август 16, 2009, 18:18 »

это специальный конструктор копирования, доступный только классу и наследникам класса.
Записан
Rcus
Гость
« Ответ #4 : Август 16, 2009, 18:24 »

это специальный конструктор копирования, доступный только классу и наследникам класса.
/*начинает сомневаться в своей способности читать код*/
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #5 : Август 16, 2009, 18:35 »

Цитировать
это специальный конструктор копирования, доступный только классу и наследникам класса.
а как может копироваться? если копирование отключено? :
Код:
private:
    Q_DECLARE_PRIVATE(QAbstractSocket)
    Q_DISABLE_COPY(QAbstractSocket)
Записан

ArchLinux x86_64 / Win10 64 bit
Alex Custov
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2063


Просмотр профиля
« Ответ #6 : Август 16, 2009, 23:38 »

тьху, не копирования, конечно, а обычный. Надо меньше работать по воскресеньям Смеющийся
Записан
ритт
Гость
« Ответ #7 : Август 17, 2009, 06:47 »

1. так я не понял все-таки... зачем делать d_func() в примерах, которые я выше привел нельзя ли это же сделать через d?
Q_D(Class); return d->something;
и
return d_func()->something;
равноценны. а вот где требуетсяб олее одного обращения к d_func(), уже выгоднее использовать Q_D()

2. и еще зачем в протектед секцию добавляют еще один QAbstractSocket :
Код:
class Q_NETWORK_EXPORT QAbstractSocket : public QIODevice
{
    Q_OBJECT
public:
...
    QAbstractSocket(SocketType socketType, QObject *parent);
...
protected:
...
    QAbstractSocket(SocketType socketType, QAbstractSocketPrivate &dd, QObject *parent = 0);
...

}
это очень хорошо, что имеется такой защищённый метод - наследников писать проще.
но для тебя данный метод бесполезен, пока не подключишь цепочку заголовков QAbstractSocketPrivate -> QObjectPrivate (что чревато и о чём дудонит каждый такой _p.h)

а вообще, прочти хотя бы http://en.wikipedia.org/wiki/D-pointer (последнее время ссылка становится всё более популярной Улыбающийся )
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #8 : Август 17, 2009, 07:22 »

2 Константин ,

спасибо огромное! Вот именно так я хотел услышать подтверждение моим мыслям Улыбающийся

Тема пока не закрыта, буду пробовать !
Записан

ArchLinux x86_64 / Win10 64 bit
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.07 секунд. Запросов: 22.