crossplatform.ru

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

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> Небольшие проблемы с QSharedPointer и Forward Declaration
SABROG
  опции профиля:
сообщение 26.5.2010, 12:16
Сообщение #1


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Проблема возникает из-за Forward Declaration тут:
namespace Ui {
    class Widget;
}

MOC еще не сгенерил .cpp файлы и размер класса еще не известен. Как я понял размер класса нужен QSharedPointer для удаления указателя, но например в таком случае все великолепно:
main.cpp
#include <QtCore/QCoreApplication>
#include <QtCore/QSharedPointer>

class Data;

class Object : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QSharedPointer<Data> value READ value WRITE setValue)

public:
    QSharedPointer<Data> value() const {return m_value;}
    void setValue(QSharedPointer<Data> value) {m_value = value;}

private:
    QSharedPointer<Data> m_value;
};

struct Data
{
    int m_value;
    float m_value2;
};

int main(int argc, char **argv)
{
    QCoreApplication a(argc, argv);
    Object obj;
    obj.setValue(QSharedPointer<Data>(new Data));
    obj.value()->m_value = 1;
    obj.value()->m_value2 = 2;

    return 0;
}

#include "moc_main.cpp"

Проблемные исходники:
Widget.h
#ifndef WIDGET_H
#define WIDGET_H

#include <QtGui/QWidget>

namespace Ui {
    class Widget;
}

class Widget : public QWidget {
    Q_OBJECT
    Q_PROPERTY(QSharedPointer<Ui::Widget> ui READ ui WRITE setUi)
public:
    Widget(QWidget* parent = 0);
    QSharedPointer<Ui::Widget> ui() const {return m_ui;}
    void setUi(QSharedPointer<Ui::Widget> ui) {m_ui = ui;}
    ~Widget();

protected:
    void changeEvent(QEvent* e);

private:
    QSharedPointer<Ui::Widget> m_ui;
};

#endif // WIDGET_H
Widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget* parent) :
    QWidget(parent)
{
    setUi(QSharedPointer<Ui::Widget>(new Ui::Widget));
    ui()->setupUi(this);
}

Widget::~Widget()
{
}

void Widget::changeEvent(QEvent* e)
{
    QWidget::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui()->retranslateUi(this);
        break;
    default:
        break;
    }
}

Предупреждения компилятора

Выполняется сборка проекта q_property_widget...
Запускается: /usr/bin/make clean -w
make: Вход в каталог `/home/sabrog/work/q_property_widget'
make: *** Нет правила для сборки цели `clean'. Останов.
make: Выход из каталога `/home/sabrog/work/q_property_widget'
Завершено с кодом 2.
Запускается: /opt/qtsdk-2010.02/qt/bin/qmake /home/sabrog/work/q_property_widget/q_property_widget.pro -spec linux-g++ -r CONFIG+=debug
Завершено с кодом 0.
Запускается: /usr/bin/make -w
make: Вход в каталог `/home/sabrog/work/q_property_widget'
/opt/qtsdk-2010.02/qt/bin/uic widget.ui -o ui_widget.h
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. -o main.o main.cpp
In file included from /opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer.h:52,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpixmap.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/qbrush.h:53,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpalette.h:47,
from /opt/qtsdk-2010.02/qt/include/QtGui/qwidget.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/QWidget:1,
from widget.h:4,
from main.cpp:2:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h: In member function ‘void QtSharedPointer::ExternalRefCount<T>::internalDestroy() [with T = Ui::Widget]’:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:329: instantiated from ‘bool QtSharedPointer::ExternalRefCount<T>::deref() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:380: instantiated from ‘QtSharedPointer::ExternalRefCount<T>::~ExternalRefCount() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:441: instantiated from here
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: possible problem detected in invocation of delete operator:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: invalid use of incomplete type ‘struct Ui::Widget’
widget.h:7: warning: forward declaration of ‘struct Ui::Widget’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. -o widget.o widget.cpp
/opt/qtsdk-2010.02/qt/bin/moc -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. widget.h -o moc_widget.cpp
g++ -c -pipe -g -Wall -W -D_REENTRANT -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2010.02/qt/mkspecs/linux-g++ -I. -I/opt/qtsdk-2010.02/qt/include/QtCore -I/opt/qtsdk-2010.02/qt/include/QtGui -I/opt/qtsdk-2010.02/qt/include -I. -I. -o moc_widget.o moc_widget.cpp
In file included from /opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer.h:52,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpixmap.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/qbrush.h:53,
from /opt/qtsdk-2010.02/qt/include/QtGui/qpalette.h:47,
from /opt/qtsdk-2010.02/qt/include/QtGui/qwidget.h:49,
from /opt/qtsdk-2010.02/qt/include/QtGui/QWidget:1,
from widget.h:4,
from moc_widget.cpp:10:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h: In member function ‘void QtSharedPointer::ExternalRefCount<T>::internalDestroy() [with T = Ui::Widget]’:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:329: instantiated from ‘bool QtSharedPointer::ExternalRefCount<T>::deref() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:380: instantiated from ‘QtSharedPointer::ExternalRefCount<T>::~ExternalRefCount() [with T = Ui::Widget]’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:441: instantiated from here
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: possible problem detected in invocation of delete operator:
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: warning: invalid use of incomplete type ‘struct Ui::Widget’
widget.h:7: warning: forward declaration of ‘struct Ui::Widget’
/opt/qtsdk-2010.02/qt/include/QtCore/qsharedpointer_impl.h:391: note: neither the destructor nor the class-specific operator delete will be called, even if they are declared when the class is defined.
g++ -Wl,-rpath,/opt/qtsdk-2010.02/qt/lib -o q_property_widget main.o widget.o moc_widget.o -L/opt/qtsdk-2010.02/qt/lib -lQtGui -L/opt/qtsdk-2010.02/qt/lib -L/usr/X11R6/lib -lQtCore -lpthread
make: Выход из каталога `/home/sabrog/work/q_property_widget'
Завершено с кодом 0.




Прикрепленные файлы
Прикрепленный файл  q_property_widget.tar.gz ( 1.05 килобайт ) Кол-во скачиваний: 206
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 26.5.2010, 15:53
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

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




Репутация:   2  


а чем std::shared_ptr или boost::shared_ptr не устроили?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 26.5.2010, 16:16
Сообщение #3


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Цитата(DEADHUNT @ 26.5.2010, 16:53) *
а чем std::shared_ptr или boost::shared_ptr не устроили?


Первый тем, что std::tr1::shared_ptr. Второй тем, что boost. Ставить дополнительную библиотеку, когда есть QSharedPointer, нафига?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DIMEDROLL
  опции профиля:
сообщение 26.5.2010, 16:50
Сообщение #4


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

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




Репутация:   0  


Цитата(DEADHUNT @ 26.5.2010, 15:53) *
а чем std::shared_ptr или boost::shared_ptr не устроили?

предполагаю что и эти шаблоны не будут работать с forward declaration.

Цитата
Как я понял размер класса нужен QSharedPointer для удаления указателя, но например в таком случае все великолепно:

То что main.cpp компилится скорее глюк, чем правильное поведение. Насколько я понмю - шаблоны нельзя инициализировать неизвестным классом...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 27.5.2010, 7:42
Сообщение #5


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

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




Репутация:   2  


Цитата(SABROG @ 26.5.2010, 16:16) *
Первый тем, что std::tr1::shared_ptr. Второй тем, что boost. Ставить дополнительную библиотеку, когда есть QSharedPointer, нафига?

tr1 уже входит в C++0x. boost.smart_pointers ничего не требует кроме заголовочных файлов и темболее многие библиотеки из boost добавляются в стандарт.

Цитата(DIMEDROLL @ 26.5.2010, 16:50) *
предполагаю что и эти шаблоны не будут работать с forward declaration.

будут.
Цитата(DIMEDROLL @ 26.5.2010, 16:50) *
Насколько я понмю - шаблоны нельзя инициализировать неизвестным классом...

undefined behavior.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 27.5.2010, 8:48
Сообщение #6


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Цитата(DEADHUNT @ 27.5.2010, 8:42) *
tr1 уже входит в C++0x.


tr1 - technical report. По сути отчет от разработчиков компилятора о том, что уже готово из будущего стандарта (C++0x), который еще не вышел. Но когда он выйдет я сомневаюсь, что разработчики компиляторов сделают этот стандарт включеным "по умолчанию". Если они так поступят, то огромное количество приложений, поддержка, которых давно закончилась, просто перестанет собираться без какого-нибудь ключа типа "-std=c++98". Кроме того существуют платформы, где используются старые версии gcc (сделали один раз порт под платформу и забросили), на них конечно никакие программы на Qt написанные с использованием нового стандарта собираться не будут.

Но я уже выбрал, что хотел, тема о другом. Если это баг, то надо писать троллям, если нет, то смирюсь и пойду дальше.
---
Сделал так для проверки. Всё собирается без предупреждений. Пойду делать багрепорт.
#include <QtGui/QWidget>

#if 0
#include <tr1/memory>
#define QSharedPointer std::tr1::shared_ptr
#endif


Сообщение отредактировал SABROG - 27.5.2010, 8:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
BRE
  опции профиля:
сообщение 27.5.2010, 9:01
Сообщение #7


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

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

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




Репутация:   44  


Цитата(SABROG @ 27.5.2010, 9:48) *
Если это баг, то надо писать троллям, если нет, то смирюсь и пойду дальше.

Компилятор не может развернуть шаблон не зная типов параметров.
То, что нормально собирается пример с одним файлом - не удивительно, компилятор находит описание структуры, даже если она описана позже, но находится в одной единице компиляции (в одном файле).
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
SABROG
  опции профиля:
сообщение 27.5.2010, 11:21
Сообщение #8


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

Группа: Участник
Сообщений: 1207
Регистрация: 8.12.2008
Из: Russia, Moscow
Пользователь №: 446

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




Репутация:   34  


Логически ведь получается такая схема:
- moc генерит .cpp файлы
- компилятор собирает все модули

Стало быть на втором этапе ему должно быть всё известно, moc же вызывается до компиляции, а не после.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DIMEDROLL
  опции профиля:
сообщение 27.5.2010, 11:51
Сообщение #9


Участник
**

Группа: Участник
Сообщений: 165
Регистрация: 28.9.2008
Из: Киев
Пользователь №: 304

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




Репутация:   0  


Цитата(DEADHUNT @ 27.5.2010, 7:42) *
будут.
...
undefined behavior.

так будут работать или undefined behavior?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
DEADHUNT
  опции профиля:
сообщение 27.5.2010, 11:59
Сообщение #10


Активный участник
***

Группа: Участник
Сообщений: 430
Регистрация: 15.4.2009
Пользователь №: 686

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




Репутация:   2  


Цитата(DIMEDROLL @ 27.5.2010, 12:51) *
так будут работать или undefined behavior?

стандарт посмотри там написано неопределённое поведение, но во многих компиляторах это разрешается.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 22.9.2019, 12:47