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

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

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Использование приватных классов. Проблемы. [НЕ РЕШЕНО]  (Прочитано 14762 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

Доброго времени суто!


При создании классов использующих QObjectPrivate, QIODevicePrivate возникли ошибки и непонятки:

1. Непонятно откуда брать хейдеры private/qinternal_p.h,  private/qiodevice_p.h: и т.п. Просмотрел исходники QT - и там хейдеры именно так и подключаются, но когда я подключаю их себе - то в консоль сыпятся ошибки:
Цитировать
...
abstractserial_p.h:7:33: error: private/qinternal_p.h: Нет такого файла или каталога
abstractserial_p.h:8:33: error: private/qiodevice_p.h: Нет такого файла или каталога
...

2. Не могу разобраться с макросами q_func() и т.п. Постоянно сырятся ошиьки что-то вроде:
Цитировать
...
abstractserialengine_p.h:77: ошибка: invalid use of incomplete type ‘struct QObjectPrivate’
/usr/include/QtCore/qobject.h:66: ошибка: forward declaration of ‘struct QObjectPrivate’
abstractserialengine_p.h: In member function ‘AbstractSerialEngine* AbstractSerialEnginePrivate::q_func()’:
abstractserialengine_p.h:78: ошибка: нет декларации ‘q_ptr’ в этой области видимости
abstractserialengine_p.h: In member function ‘const AbstractSerialEngine* AbstractSerialEnginePrivate::q_func() const’:
abstractserialengine_p.h:78: ошибка: нет декларации ‘q_ptr’ в этой области видимости
In file included from abstractserial_p.h:5,
                 from abstractserial.cpp:25:
nativeserialengine_p.h: In member function ‘NativeSerialEngine* NativeSerialEnginePrivate::q_func()’:
nativeserialengine_p.h:68: ошибка: нет декларации ‘q_ptr’ в этой области видимости
nativeserialengine_p.h: In member function ‘const NativeSerialEngine* NativeSerialEnginePrivate::q_func() const’:
nativeserialengine_p.h:68: ошибка: нет декларации ‘q_ptr’ в этой области видимости
In file included from abstractserial.cpp:25:
abstractserial_p.h: At global scope:
abstractserial_p.h:13: ошибка: invalid use of incomplete type ‘struct QIODevicePrivate’
/usr/include/QtCore/qiodevice.h:63: ошибка: forward declaration of ‘struct QIODevicePrivate’
abstractserial_p.h: In member function ‘AbstractSerial* AbstractSerialPrivate::q_func()’:
abstractserial_p.h:14: ошибка: нет декларации ‘q_ptr’ в этой области видимости
abstractserial_p.h: In member function ‘const AbstractSerial* AbstractSerialPrivate::q_func() const’:
abstractserial_p.h:14: ошибка: нет декларации ‘q_ptr’ в этой области видимости
abstractserial.cpp: In member function ‘bool AbstractSerialPrivate::initSerialLayer()’:
abstractserial.cpp:79: ошибка: нет декларации ‘resetSocketLayer’ в этой области видимости
abstractserial.cpp: In constructor ‘AbstractSerial::AbstractSerial(const QString&, QObject*)’:
abstractserial.cpp:168: ошибка: нет подходящей функции для вызова ‘QIODevice::QIODevice(AbstractSerialPrivate&, QObject*&)’
/usr/include/QtCore/qiodevice.h:166: замечание: претенденты: QIODevice::QIODevice(const QIODevice&)
/usr/include/QtCore/qiodevice.h:150: замечание:              QIODevice::QIODevice(QIODevicePrivate&, QObject*)
/usr/include/QtCore/qiodevice.h:88: замечание:              QIODevice::QIODevice(QObject*)
/usr/include/QtCore/qiodevice.h:86: замечание:              QIODevice::QIODevice()
abstractserial.cpp: In member function ‘QStringList AbstractSerial::serialDevicesAvailable() const’:
abstractserial.cpp:313: ошибка: no match for ternary ‘operator?:’ in ‘AbstractSerial::isValid() ? AbstractSerialEngine::serialDevicesAvailable() : 0’
make: *** [build/obj/abstractserial.o] Ошибка 1
[den@myhost src]$                                                                                
...

Я "слизал" структуру классов аналогично классам в исходниках QT сокетов, и не пойму в чем ошибки .  Прилагаю архив с исходниками. Улыбающийся Может кто нить мне поможет разобраться в чем дело.

ЗЫ: эти исходники - попытка создать библиотеку для работы с последовательным портом по всем принципам QT4 и т.п.
ЗЫЗЫ: собирать пока что нужно пробовать в *.nix (под винду не готово еще)

Оч жду помощи!
« Последнее редактирование: Август 27, 2009, 14:40 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
denka
Гость
« Ответ #1 : Август 23, 2009, 20:19 »

Насчет инклюда приват классов :

Module/private/include.h

На пример:

Код:
#include <QtCore/private/qobject_p.h>
#include <QtGui/private/qwidget_p.h>
Записан
ритт
Гость
« Ответ #2 : Август 23, 2009, 21:15 »

эти инклюды доступны только в source-tree и недоступны после установки.
Записан
BlackTass
Гость
« Ответ #3 : Август 23, 2009, 21:26 »

эти инклюды доступны только в source-tree и недоступны после установки.
Плюс к этому в них должно быть написано что нефиг это использовать ибо может измениться до неузнаваемости.

Я думаю стоит не заморачиваться с наследованием приватных классов от приватных кутешных, а использовать свои.
Записан
ритт
Гость
« Ответ #4 : Август 24, 2009, 00:17 »

эти инклюды доступны только в source-tree и недоступны после установки.
Плюс к этому в них должно быть написано что нефиг это использовать ибо может измениться до неузнаваемости.

Я думаю стоит не заморачиваться с наследованием приватных классов от приватных кутешных, а использовать свои.
именно. использовние данных хедеров - дело персональное, но лучше не стОит )

если их всё же необходимо использовать для получения доступа к некоторым приватным данным из класса-наследника, советую скопировать сам приватный хедер (или цепочку хедеров) в свой проект и убрать из них всё лишнее - впоследствии будет легче поддерживать их актуальность. но такая необходимость бывает довольно редко...
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

Аха, всем спасибо за наводку, но теперь:

Цитировать
Я думаю стоит не заморачиваться с наследованием приватных классов от приватных кутешных, а использовать свои.
Цитировать
именно. использовние данных хедеров - дело персональное, но лучше не стОит )
А как свои то нарисовать (приватные классы)? Я например не представляю что туда нужно "пихать".

Цитировать
если их всё же необходимо использовать для получения доступа к некоторым приватным данным из класса-наследника, советую скопировать сам приватный хедер (или цепочку хедеров) в свой проект и убрать из них всё лишнее - впоследствии будет легче поддерживать их актуальность. но такая необходимость бывает довольно редко...
так в том и дело, что я не знаю что от туда убирать.. я щас глянул исходники QObjectPrivate - а там "мама не горюй! всего понапихано Грустный

1. Подскажите плз, что является лишним - а что нет в классе QObjectPrivate ? т.к. все приватные классы от него  наследуются
2. И если вдруг я решу с "нуля" создать свой приватный класс - то что в него нужно "пихать" ?

Дайте ссылки на HOWTO по использованию приватных классов и т.п. (если они имеются)

Записан

ArchLinux x86_64 / Win10 64 bit
Rcus
Гость
« Ответ #6 : Август 24, 2009, 07:58 »

KISS. Предлагаю сделать один интерфейсный класс SerialDevice, в котором будет только SerialDevicePrivate *d;
в котором будут заключены все данные. Реализация будет заключена в файлах serialdeviceprivate_posix(_p.h|.cpp) и serialdeviceprivate_win(_p.h|cpp), при сборке под разными системами будут выбираться разные файлы. И никаких вам виртуальных вызовов и использования _p заголовков Qt.

А в приватный класс надо отправлять все данные, все приватные методы и все защищенные методы не являющиеся интерфейсом класса (возможно при построении иерархии)
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


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

Цитировать
KISS. Предлагаю сделать один интерфейсный класс SerialDevice, в котором будет только SerialDevicePrivate *d;
в котором будут заключены все данные. Реализация будет заключена в файлах serialdeviceprivate_posix(_p.h|.cpp) и serialdeviceprivate_win(_p.h|cpp), при сборке под разными системами будут выбираться разные файлы. И никаких вам виртуальных вызовов и использования _p заголовков Qt.
Да я тоже сначала так подумал, но изза того, что трудно разобраться в реализации таких вещей как (по аналогии с сокетами) : использование флагов , связанных с нотификаторами и т.п. - мне проще (не разбираясь в их сути и логики) просто скопировать их из сокетов.. Улыбающийся .  

Цитировать
А в приватный класс надо отправлять все данные, все приватные методы и все защищенные методы не являющиеся интерфейсом класса (возможно при построении иерархии)
Вопрос, а в таком случае этот приватный класс должен быть наследником от чего либо или же он должен быть сам по себе ? Мне вот с этим не понятно.

т.е. если например проследить (на примере сокетов) цепочку классов QObjectPrivate ->QObjectData - то в QObjectData есть следующие строки:
Код:
class QObjectData {
public:
    virtual ~QObjectData() = 0;
    QObject *q_ptr;
    QObject *parent;
    QObjectList children;
...
...
};

и в "моем" случае предполагается использование макросов     Q_D, Q_Q и т.п. .. Так вот вопрос, нужно ли при использовании этих макросов - реализовывать приватный класс с этим:
Код:
...
    QObject *q_ptr;
...

? Или же это не нужно совсем!

-----------------------------------

Прошу прощения, вот по этой ссылке: http://techbase.kde.org/Policies/Library_Code_Policy/Shared_D-Pointer_Example
вроде бы начал понимать что к чему.... Вопрос пока что приостанавливается Улыбающийся
« Последнее редактирование: Август 24, 2009, 09:22 от kuzulis » Записан

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

Сообщений: 2812


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

Что-то не хочет компилироваться вот этот пример:

mybaseclass.h
Код:
#ifndef MYBASECLASS_H
#define MYBASECLASS_H

#include <QObject>

class MyBasePrivateClass;
class MyBaseClass : public QObject
{
    Q_OBJECT
public:
MyBaseClass(QObject *parent = 0);
void setParam(int val);
int param() const;
protected:
    MyBasePrivateClass * const d_ptr;
//MyBaseClass(MyBasePrivateClass &dd, QObject *parent);
private:
    Q_DECLARE_PRIVATE(MyBaseClass)
    Q_DISABLE_COPY(MyBaseClass)
};

#endif

mybaseclass.cpp
Код:
#include "mybaseclass.h"


class MyBasePrivateClass
{
Q_DECLARE_PUBLIC(MyBaseClass)
public:
MyBasePrivateClass() { m_param = 0; }
virtual ~MyBasePrivateClass() {}
int m_param;
MyBaseClass *q_ptr;
};


MyBaseClass::MyBaseClass(QObject *parent)
    : QObject(parent), d_ptr(new MyBasePrivateClass)
{
   // Q_D(MyBaseClass);
}

void MyBaseClass::setParam(int val)
{
    Q_D(MyBaseClass);
d->m_param = val;
}

int MyBaseClass::param() const
{
    Q_D(const MyBaseClass);
return d->m_param;
}

Пишет:
Цитировать
D:\projects\Private_test\src>make
g++ -c -O2 -frtti -fexceptions -Wall -DUNICODE -DQT_LARGEFILE_SUPPORT -DQT_NO_DEBUG -DQT_CORE_LIB -D
QT_THREAD_SUPPORT -I"D:/Qt/4.1.1/include/QtCore" -I"D:/Qt/4.1.1/include" -I"D:/Qt/4.1.1/include/Acti
veQt" -I"build\moc" -I"." -I"D:/Qt/4.1.1/mkspecs/win32-g++" -o build\obj\mybaseclass.o mybaseclass.c
pp
In file included from mybaseclass.cpp:1:
mybaseclass.h:18: error: ISO C++ forbids declaration of `MyBaseClassPrivate' with no type
mybaseclass.h:18: error: `MyBaseClassPrivate' declared as an `inline' field
mybaseclass.h:18: error: expected `;' before '*' token
mybaseclass.h:18: error: expected `;' before "inline"
mybaseclass.h:18: error: ISO C++ forbids declaration of `MyBaseClassPrivate' with no type
mybaseclass.h:18: error: `MyBaseClassPrivate' declared as an `inline' field
mybaseclass.h:18: error: expected `;' before '*' token
mybaseclass.h:18: error: expected `;' before "friend"
D:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h: In member function `void MyBaseClass:
:setParam(int)':
D:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h:99: error: `QObjectPrivate* QObject::d
_func()' is private
mybaseclass.cpp:23: error: within this context
mybaseclass.cpp:23: error: cannot convert `QObjectPrivate*' to `MyBaseClassPrivate* const' in initia
lization
mybaseclass.cpp:24: error: invalid use of undefined type `struct MyBaseClassPrivate'
mybaseclass.h:18: error: forward declaration of `struct MyBaseClassPrivate'
D:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h: In member function `int MyBaseClass::
param() const':
D:/Qt/4.1.1/include/QtCore/../../src/corelib/kernel/qobject.h:99: error: `const QObjectPrivate* QObj
ect::d_func() const' is private
mybaseclass.cpp:29: error: within this context
mybaseclass.cpp:29: error: cannot convert `const QObjectPrivate*' to `MyBaseClassPrivate* const' in
initialization
mybaseclass.cpp:30: error: invalid use of undefined type `struct MyBaseClassPrivate'
mybaseclass.h:18: error: forward declaration of `struct MyBaseClassPrivate'
mingw32-make: *** [build\obj\mybaseclass.o] Error 1

D:\projects\Private_test\src>

Я уже бьюсь второй день и так и эдак меняю , переставляю члены и т.п. и все никак! Грустный

Не понимаю что ему нужно... поможите
ЗЫ:
Прикрепляю проект
Записан

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

g++ -E
Код
C++ (Qt)
# 1 "/usr/include/QtCore/QObject" 2
# 5 "mybaseclass.h" 2
 
class MyBasePrivateClass;
class MyBaseClass : public QObject
{
   public: template <typename T> inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i; } static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); static inline QString tr(const char *s, const char *c = 0) { return staticMetaObject.tr(s, c); } static inline QString trUtf8(const char *s, const char *c = 0) { return staticMetaObject.trUtf8(s, c); } static inline QString tr(const char *s, const char *c, int n) { return staticMetaObject.tr(s, c, n); } static inline QString trUtf8(const char *s, const char *c, int n) { return staticMetaObject.trUtf8(s, c, n); } virtual int qt_metacall(QMetaObject::Call, int, void **); private:
public:
MyBaseClass(QObject *parent = 0);
void setParam(int val);
int param() const;
protected:
   [b]MyBasePrivateClass[/b] * const d_ptr;
 
private:
   inline [b]MyBaseClassPrivate[/b]* d_func() { return reinterpret_cast<MyBaseClassPrivate *>(d_ptr); } inline const MyBaseClassPrivate* d_func() const { return reinterpret_cast<const MyBaseClassPrivate *>(d_ptr); } friend class MyBaseClassPrivate;
   MyBaseClass(const MyBaseClass &); MyBaseClass &operator=(const MyBaseClass &);
};
# 2 "mybaseclass.cpp" 2
 
hint Улыбающийся
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #10 : Август 25, 2009, 09:01 »

хм... а зачем так много то? я например хочу с использованием макросов - как описано тут : http://techbase.kde.org/Policies/Library_Code_Policy/Shared_D-Pointer_Example
The header file, with Q_DECLARE_PRIVATE

А теперь поясните в чем разница то?

ЗЫ: ничо не понял
« Последнее редактирование: Август 25, 2009, 09:03 от kuzulis » Записан

ArchLinux x86_64 / Win10 64 bit
BRE
Гость
« Ответ #11 : Август 25, 2009, 09:09 »

А теперь поясните в чем разница то?
ЗЫ: ничо не понял
Rcus тебе показал во что разворачивается Q_DECLARE_PRIVATE(MyBaseClass). Улыбающийся
Внимательно посмотри на имена классов которые он хотел bold-ом отметить.
 Подмигивающий
Записан
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #12 : Август 25, 2009, 09:14 »

Цитировать
Внимательно посмотри на имена классов которые он хотел bold-ом отметить.
 Подмигивающий

И? Это опять загадка? А по простому нельзя сказать да?

Ну посмотрел я код примера из ссылки где без макросов:
Код:
class KFooBasePrivate;
class KFooBase : public QObject
{
public:
    KFooBase(QObject *parent);
    void setSomeInteger(int i);
    int someInteger() const;
protected:
    KFooBasePrivate * const d_ptr;
    KFooBase(KFooBasePrivate &dd, QObject *parent);
private:
    friend class KFooBasePrivate;
    inline KFooBasePrivate *d_func() { return d_ptr; }
    inline const KFooBasePrivate *d_func() const { return d_ptr; }
};

Аналогично все, только у меня нету KFooBase(KFooBasePrivate &dd, QObject *parent); .. а так все однотипно.. и ? в чем суть?

ЗЫ: и разница MyBasePrivateClass и MyBaseClassPrivate это с чего вдруг такая? о_О
« Последнее редактирование: Август 25, 2009, 09:16 от kuzulis » Записан

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

И? Это опять загадка? А по простому нельзя сказать да?
Твой приватный класс называется MyBasePrivateClass.
Макрос Q_DECLARE_PRIVATE(MyBaseClass) добавит к MyBaseClass слово Private и получиться MyBaseClassPrivate.
Сравни написание.
Записан
Rcus
Гость
« Ответ #14 : Август 25, 2009, 09:21 »

Вот же как, загадка была в вашем вопросе, я ее решил и показал решение, надо было лишь внимательно прочитать. В печаль меня вгоняют подобные явления. /** уходит совещаться с собой по поводу насущной проблемы имитации сценариев для тестирования устройств */
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


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