Название: Использование приватных классов. Проблемы. [НЕ РЕШЕНО] Отправлено: kuzulis от Август 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 (под винду не готово еще) Оч жду помощи! Название: Re: Использование приватных классов. Проблемы. Отправлено: denka от Август 23, 2009, 20:19 Насчет инклюда приват классов :
Module/private/include.h На пример: Код: #include <QtCore/private/qobject_p.h> Название: Re: Использование приватных классов. Проблемы. Отправлено: ритт от Август 23, 2009, 21:15 эти инклюды доступны только в source-tree и недоступны после установки.
Название: Re: Использование приватных классов. Проблемы. Отправлено: BlackTass от Август 23, 2009, 21:26 эти инклюды доступны только в source-tree и недоступны после установки. Плюс к этому в них должно быть написано что нефиг это использовать ибо может измениться до неузнаваемости.Я думаю стоит не заморачиваться с наследованием приватных классов от приватных кутешных, а использовать свои. Название: Re: Использование приватных классов. Проблемы. Отправлено: ритт от Август 24, 2009, 00:17 эти инклюды доступны только в source-tree и недоступны после установки. Плюс к этому в них должно быть написано что нефиг это использовать ибо может измениться до неузнаваемости.Я думаю стоит не заморачиваться с наследованием приватных классов от приватных кутешных, а использовать свои. если их всё же необходимо использовать для получения доступа к некоторым приватным данным из класса-наследника, советую скопировать сам приватный хедер (или цепочку хедеров) в свой проект и убрать из них всё лишнее - впоследствии будет легче поддерживать их актуальность. но такая необходимость бывает довольно редко... Название: Re: Использование приватных классов. Проблемы. Отправлено: kuzulis от Август 24, 2009, 07:34 Аха, всем спасибо за наводку, но теперь:
Цитировать Я думаю стоит не заморачиваться с наследованием приватных классов от приватных кутешных, а использовать свои. Цитировать именно. использовние данных хедеров - дело персональное, но лучше не стОит ) А как свои то нарисовать (приватные классы)? Я например не представляю что туда нужно "пихать".Цитировать если их всё же необходимо использовать для получения доступа к некоторым приватным данным из класса-наследника, советую скопировать сам приватный хедер (или цепочку хедеров) в свой проект и убрать из них всё лишнее - впоследствии будет легче поддерживать их актуальность. но такая необходимость бывает довольно редко... так в том и дело, что я не знаю что от туда убирать.. я щас глянул исходники QObjectPrivate - а там "мама не горюй! всего понапихано :(1. Подскажите плз, что является лишним - а что нет в классе QObjectPrivate ? т.к. все приватные классы от него наследуются 2. И если вдруг я решу с "нуля" создать свой приватный класс - то что в него нужно "пихать" ? Дайте ссылки на HOWTO по использованию приватных классов и т.п. (если они имеются) Название: Re: Использование приватных классов. Проблемы. Отправлено: Rcus от Август 24, 2009, 07:58 KISS. Предлагаю сделать один интерфейсный класс SerialDevice, в котором будет только SerialDevicePrivate *d;
в котором будут заключены все данные. Реализация будет заключена в файлах serialdeviceprivate_posix(_p.h|.cpp) и serialdeviceprivate_win(_p.h|cpp), при сборке под разными системами будут выбираться разные файлы. И никаких вам виртуальных вызовов и использования _p заголовков Qt. А в приватный класс надо отправлять все данные, все приватные методы и все защищенные методы не являющиеся интерфейсом класса (возможно при построении иерархии) Название: Re: Использование приватных классов. Проблемы. Отправлено: kuzulis от Август 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 { и в "моем" случае предполагается использование макросов Q_D, Q_Q и т.п. .. Так вот вопрос, нужно ли при использовании этих макросов - реализовывать приватный класс с этим: Код: ... ? Или же это не нужно совсем! ----------------------------------- Прошу прощения, вот по этой ссылке: http://techbase.kde.org/Policies/Library_Code_Policy/Shared_D-Pointer_Example вроде бы начал понимать что к чему.... Вопрос пока что приостанавливается :) Название: Re: Использование приватных классов. Проблемы. Отправлено: kuzulis от Август 25, 2009, 08:32 Что-то не хочет компилироваться вот этот пример:
mybaseclass.h Код: #ifndef MYBASECLASS_H mybaseclass.cpp Код: #include "mybaseclass.h" Пишет: Цитировать 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> Я уже бьюсь второй день и так и эдак меняю , переставляю члены и т.п. и все никак! :( Не понимаю что ему нужно... поможите ЗЫ: Прикрепляю проект Название: Re: Использование приватных классов. Проблемы. Отправлено: Rcus от Август 25, 2009, 08:45 g++ -E
Код hint :) Название: Re: Использование приватных классов. Проблемы. Отправлено: kuzulis от Август 25, 2009, 09:01 хм... а зачем так много то? я например хочу с использованием макросов - как описано тут : http://techbase.kde.org/Policies/Library_Code_Policy/Shared_D-Pointer_Example
The header file, with Q_DECLARE_PRIVATE А теперь поясните в чем разница то? ЗЫ: ничо не понял Название: Re: Использование приватных классов. Проблемы. Отправлено: BRE от Август 25, 2009, 09:09 А теперь поясните в чем разница то? Rcus тебе показал во что разворачивается Q_DECLARE_PRIVATE(MyBaseClass). :)ЗЫ: ничо не понял Внимательно посмотри на имена классов которые он хотел bold-ом отметить. ;) Название: Re: Использование приватных классов. Проблемы. Отправлено: kuzulis от Август 25, 2009, 09:14 Цитировать Внимательно посмотри на имена классов которые он хотел bold-ом отметить. Подмигивающий И? Это опять загадка? А по простому нельзя сказать да? Ну посмотрел я код примера из ссылки где без макросов: Код: class KFooBasePrivate; Аналогично все, только у меня нету KFooBase(KFooBasePrivate &dd, QObject *parent); .. а так все однотипно.. и ? в чем суть? ЗЫ: и разница MyBasePrivateClass и MyBaseClassPrivate это с чего вдруг такая? о_О Название: Re: Использование приватных классов. Проблемы. Отправлено: BRE от Август 25, 2009, 09:17 И? Это опять загадка? А по простому нельзя сказать да? Твой приватный класс называется MyBasePrivateClass.Макрос Q_DECLARE_PRIVATE(MyBaseClass) добавит к MyBaseClass слово Private и получиться MyBaseClassPrivate. Сравни написание. Название: Re: Использование приватных классов. Проблемы. Отправлено: Rcus от Август 25, 2009, 09:21 Вот же как, загадка была в вашем вопросе, я ее решил и показал решение, надо было лишь внимательно прочитать. В печаль меня вгоняют подобные явления. /** уходит совещаться с собой по поводу насущной проблемы имитации сценариев для тестирования устройств */
Название: Re: Использование приватных классов. Проблемы. Отправлено: kuzulis от Август 25, 2009, 09:24 О_О ёпт!
никогда бы не подумал что макрос чо-то добавит сам !!! О_О О_О О_О О_О Огромное Rcus + BRE человеческое Спасибо! :) И на это я убил 2 дня ... мдя.. и мне тож грустно Получается , что "как ты лодку назовешь - так она и поплывет" (с) И главное - что нигде нет упоминания (по крайней мере я не нашел) где говорилось бы о "правильности составления имени класса" Название: Re: Использование приватных классов. Проблемы. Отправлено: BRE от Август 25, 2009, 09:35 И главное - что нигде нет упоминания (по крайней мере я не нашел) где говорилось бы о "правильности составления имени класса" Как это нигде, а в /src/corelib/global/global.h ;)[Как мне показалось, Rcus своим ответом и хотел что бы ты туда заглянул. :) ] Название: Re: Использование приватных классов. Проблемы. [РЕШЕНО] Отправлено: kuzulis от Август 25, 2009, 09:39 Кстати, а обязательно добавлять в protected секцию это:
Код: protected: ? И для чего оно нужно? Название: Re: Использование приватных классов. Проблемы. [РЕШЕНО] Отправлено: Rcus от Август 25, 2009, 09:46 Не обязательно. Нужно разработчику библиотеки чтобы использовать наследование интерфейсного класса совместно с раширением приватного класса.
Название: Re: Использование приватных классов. Проблемы. [РЕШЕНО] Отправлено: kuzulis от Август 25, 2009, 09:51 Спс :)
Название: Re: Использование приватных классов. Проблемы. [НЕ РЕШЕНО] Отправлено: kuzulis от Август 27, 2009, 14:43 Да чтож такое! Не собирается тестовый примерчик с приватными классами, пишет при сборке:
Цитировать build\obj\mybaseclass.o(.text+0x0):mybaseclass.cpp: multiple definition of `MyBaseClass::MyBaseClass (QObject*)' build\obj\mybaseclass.o(.text+0x0):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0xd0):mybaseclass.cpp: multiple definition of `MyBaseClass::MyBaseClas s(QObject*)' build\obj\mybaseclass.o(.text+0xd0):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x1a0):mybaseclass.cpp: multiple definition of `MyBaseClass::MyBaseCla ss(MyBaseClassPrivate&, QObject*)' build\obj\mybaseclass.o(.text+0x1a0):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x1d0):mybaseclass.cpp: multiple definition of `MyBaseClass::MyBaseCla ss(MyBaseClassPrivate&, QObject*)' build\obj\mybaseclass.o(.text+0x1d0):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x200):mybaseclass.cpp: multiple definition of `MyBaseClass::~MyBaseCl ass()' build\obj\mybaseclass.o(.text+0x200):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x2c0):mybaseclass.cpp: multiple definition of `MyBaseClass::~MyBaseCl ass()' build\obj\mybaseclass.o(.text+0x2c0):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x380):mybaseclass.cpp: multiple definition of `MyBaseClass::~MyBaseCl ass()' build\obj\mybaseclass.o(.text+0x380):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x450):mybaseclass.cpp: multiple definition of `MyBaseClass::setParam( int)' build\obj\mybaseclass.o(.text+0x450):mybaseclass.cpp: first defined here build\obj\mybaseclass.o(.text+0x470):mybaseclass.cpp: multiple definition of `MyBaseClass::param() c onst' build\obj\mybaseclass.o(.text+0x470):mybaseclass.cpp: first defined here build\obj\main.o(.text+0x8d):main.cpp: undefined reference to `MyClass::MyClass(QObject*)' collect2: ld returned 1 exit status mingw32-make: *** [release\testprivate.exe] Error 1 что ему теперь нужно? ЗЫ: я злой ппц . пример прилагаю Название: Re: Использование приватных классов. Проблемы. [НЕ РЕШЕНО] Отправлено: BRE от Август 27, 2009, 14:56 Смотри src.pro:
- SOURCES = mybaseclass.cpp mybaseclass.cpp main.cpp + SOURCES = mybaseclass.cpp myclass.cpp main.cpp myclass.h: protected: - MyClass(MyClass &dd, QObject *parent); + MyClass(MyClassPrivate &dd, QObject *parent); И не нервничай так. ;) Название: Re: Использование приватных классов. Проблемы. [НЕ РЕШЕНО] Отправлено: kuzulis от Август 27, 2009, 15:02 Упс, спасибо! :)
|