crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Непонятные проблемы с vtable
Гость_Михаил_*
сообщение 9.8.2009, 20:05
Сообщение #1





Гости








    


Здравствуйте уважаемые знатоки. Начинаю учить тонкости Qt (MinGW + Qt 4.5.1 + Eclipse + Qt Integration)
Делаю следующее:
ViewFactory.h
class ViewFactory {
public:
    virtual QObject * newInstance() const = 0;
    virtual QString getFactoryName() const = 0;
    virtual QString getFactoryDesc() const = 0;
};

Q_DECLARE_INTERFACE(ViewFactory,"com.tisadb.ViewFactory\0.1")

Потом:
tableview.h
class tableviewFactory : public QObject, public ViewFactory
{
    Q_OBJECT
    Q_INTERFACES(ViewFactory)
public:
    QObject * newInstance() const { return const_cast<QObject *>((QObject *)new tableview()); };
    QString getFactoryName() const { return QString("TableView"); };
    QString getFactoryDesc() const { return QString("TableView version 0.1"); };
};


Если в таком виде компилирую проект то все работает нормально но если пытаюсь сделать более универсальный код:
Factory.h
#define FACTORY_INTERFACE(INTERFACE,INTERFACEDESC) \
class INTERFACE##Factory { \
    public: \
        virtual QObject * newInstance() const = 0; \
        virtual QString getFactoryName() const = 0; \
        virtual QString getFactoryDesc() const = 0; \
}; \
Q_DECLARE_INTERFACE(INTERFACE##Factory,INTERFACEDESC)

#define FACTORY(CLASS,INTERFACE,CLASSNAME,CLASSDESC) \
class CLASS##Factory : public QObject, public INTERFACE##Factory { \
    Q_OBJECT \
    Q_INTERFACES(INTERFACE##Factory) \
    public: \
        QObject * newInstance() const { return const_cast<QObject *>((QObject *)new CLASS()); }; \
        QString getFactoryName() const { return QString(CLASSNAME); }; \
        QString getFactoryDesc() const { return QString(CLASSDESC); }; \
};

ViewFactory.h
FACTORY_INTERFACE(View,"com.tisadb.ViewFactory\0.1")

tableview.h
FACTORY(tableview,View,"TableView","TableView verson 0.1")

Если же в этом случае компилирую проэкт, то при линковке выводится ошибка:
(.text$_ZN16tableviewFactoryC1Ev[tableviewFactory::tableviewFactory()]+0x2e): undefined reference to `vtable for tableviewFactory'
D:/Devel/tisaprj/tableview/../../qt-win-opensource-src-4.5.1/include/QtCore/../../src/corelib/tools/qlist.h:(.text$_ZN16tableviewFactoryC1Ev[tableviewFactory::tableviewFactory()]+0x3a): undefined reference to `vtable for tableviewFactory'
Причина редактирования: Используй тэг code
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 9.8.2009, 20:11
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Это происходит скорее всего из-за того, что moc не распознает класс с Q_OBJECT, который делается с помощью #define FACTORY.
moc парсит исходники до отработки препроцессора и такие подстановки делать не умеет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 9.8.2009, 20:13
Сообщение #3





Гости








    


И какой может быть выход?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 9.8.2009, 20:16
Сообщение #4





Гости








    


Тем более судя по исходникам эту подстановку делает не moc а препроцессор GCC, а moc - обраватыват только xml-ки и подставляет из вывод в соответствующие файлы
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 9.8.2009, 20:21
Сообщение #5





Гости








    


Нет, вижу, действительно может moc виноват, и какой может быть выход?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 9.8.2009, 20:22
Сообщение #6


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Гость_Гость_* @ 10.8.2009, 0:16) *
moc - обраватыват только xml
moc вообще их читать не умеет, ты путаешь его либо с rcc либо с uic
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 9.8.2009, 20:25
Сообщение #7





Гости








    


Дык это я уже понял
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 9.8.2009, 20:33
Сообщение #8


Профессионал
*****

Группа: Участник
Сообщений: 1112
Регистрация: 6.3.2009
Из: Ростов-на-Дону
Пользователь №: 591

Спасибо сказали: 264 раз(а)




Репутация:   44  


Цитата(Гость @ 9.8.2009, 21:21) *
Нет, вижу, действительно может moc виноват, и какой может быть выход?

moc пробегается по исходникам и выбирает классы, в которых есть макрос Q_OBJECT, и для этих классов генерируется специальные файлы moc_*.cpp.
Поэтому, для правильной генерации этих файлов необходимо, что бы moc находил в классе макрос Q_OBJECT, т.е.:
class Obj : public QObject
{
    Q_OBJECT
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 9.8.2009, 20:44
Сообщение #9


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Гость_Михаил_* @ 10.8.2009, 0:05) *
но если пытаюсь сделать более универсальный код
по моему разумению, универсальный код не строится на макросах вообще. Нужно искать решение в методах (шаблонах) проектирования.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Гость_Гость_*
сообщение 9.8.2009, 20:57
Сообщение #10





Гости








    


Короче решил проблему так:
Factory.h
#define FACTORY_INTERFACE \
virtual QObject * newInstance() const = 0; \
virtual QString getFactoryName() const = 0; \
virtual QString getFactoryDesc() const = 0; \


#define FACTORY(CLASS,CLASSNAME,CLASSDESC) \
public: \
QObject * newInstance() const { return const_cast<QObject *>((QObject *)new CLASS()); }; \
QString getFactoryName() const { return QString(CLASSNAME); }; \
QString getFactoryDesc() const { return QString(CLASSDESC); }; \
private:

ViewFactory.h
class ViewFactory {
public:
FACTORY_INTERFACE
};

Q_DECLARE_INTERFACE(ViewFactory,"com.tisadb.ViewFactory\0.1")

tableview.h
class tableviewFactory : public QObject, public ViewFactory
{
Q_OBJECT
Q_INTERFACES(ViewFactory)
public:
FACTORY(tableview,"TableView", "TableView version 0.1")
};

Конечно не то что хотелось бы, если у кого будут еще сообращения - делитесь
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

2 страниц V   1 2 >
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


11 чел. читают эту тему (гостей: 11, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 2.12.2024, 6:14