Russian Qt Forum

Qt => Общие вопросы => Тема начата: xintrea от Октября 08, 2008, 23:36



Название: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 08, 2008, 23:36
Здравствуйте!


Сделал себе искалку объектов по имени. С надеждой, что имея её, я всегда смогу достучаться до нужного объекта, и вызвать у этого объекта нужный метод.

Искалка реализована так. Имеется глобальная переменная (знаю что не хорошо, но пока так), которая хранит указатель на виджет основного окна. Это стартовая точка поиска. Далее рекурсивно просматриваются children для поиска нужного объекта по имени.

Код:
QObject *mainwindowpointer;

QObject *find_object_recurse(QObject *pobj,QString n)
{
 QObjectList olist;

 olist=pobj->children();

 for(int i=0;i<olist.size();++i)
  {
   QObject *currobj;
   currobj=olist.at(i);

   qDebug() << "Object " << currobj->objectName();

   if(n==currobj->objectName()) return currobj;
   else return find_object_recurse(currobj,n);
  }

 return NULL;
}

QObject *find_object(QString n)
{
 qDebug() << "Find object " << n << "...";

 QObject *findobj;

 findobj=find_object_recurse(mainwindowpointer,n); // Вызывается рекурсивный поиск

 if(findobj==NULL)
  {
   qDebug() << "Try find unavaiable object " << n;
   exit(1);
  }
 else
  return findobj;
}


Инициализация начальной точки просходит очень просто:

Код:
int main(int argc, char ** argv)
{
 QApplication app( argc, argv );

 mainwindow win; // класс mainwindow - это виджет основного окна
 mainwindowpointer=&win; // инициализация стартовой точки поиска объектов

 win.show();

 return app.exec();
}


Чтобы узнать указатель на объект, теперь можно из любой части программы вызвать функцию

Код:
find_object("objectname")

и эта функция вернет указатель на найденый объект (если ему, конечно, было задано имя через setObjectName() ). Дело осложняется тем, что указатель этот будет типа (QObject *). А для того, чтобы вызвать метод объекта, надо иметь указатель того типа, которым объект объявлен.

И вот тут я дальше не знаю что делать. Пробовал делать по-всякому явное преобразование типов, ну например

Код:
(editor)find_object("editorinstance")

но тогда не идет компиляция, пишет что "некорректное преобразование из 'QObject*' в 'QWidget*'". По-всякому пробовал - результата не получил.


Вопрос. Есть ли воможность в Qt преобразовывать указатели на QObject в тип того объекта, на который этот же указатель и показывает? Как это сделать? Если никак, то каким методом можно решить задачу поиска объекта и получения на него указателя, с последующим использованием этого указателя для доступа к методам объекта?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Rcus от Октября 09, 2008, 00:28
Все это уже есть в QT, даже глобальный указатель (правда не на главное окно, а на QCoreApplication(QApplication для программ с гуем), таким образом если немного изменить main
Код:
int main(int argc, char ** argv)
{
 QApplication app( argc, argv );

 mainwindow* win = new mainwindow(app);
 win->show();

 return app.exec();
}
то можно будет искать нужные объекты используя метод T QObject::findChild ( const QString & name = QString() ) const,
например так:
Код:
qApp->findChild<QAction*>("actionExit")->trigger();


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 09, 2008, 01:00
findChild() ищет рекурсивно, или только объекты, являющиеся children для обрабатываемого объекта ( в вашем случае qApp) ?

Другими словами, можете ли вы, ну, скажем, поменять текст кнопки, которая лежит на виджете, который входит в состав другого виджета, который лежит на главном окне? Причем сделать это не зная пути от главного окна до кнопки?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Rcus от Октября 09, 2008, 01:13
Цитировать
T QObject::findChild ( const QString & name = QString() ) const
Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. Omitting the name argument causes all object names to be matched. The search is performed recursively.
assistant пишет что поиск выполняется рекурсивно в ширину.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 09, 2008, 01:25
используй findChild() и qobject_cast с шаблоном. имя класса можно получить из метаобъекта


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 09, 2008, 11:55
2 xintrea: Вы путаете понятия "ссылка" и "указатель". Было бы неплохо, если бы вы подредактировали свой пост и название темы


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 09, 2008, 22:21
Все это уже есть в QT, даже глобальный указатель (правда не на главное окно, а на QCoreApplication(QApplication для программ с гуем)

можно искать нужные объекты используя метод T QObject::findChild ( const QString & name = QString() ) const,
например так:
Код:
qApp->findChild<QAction*>("actionExit")->trigger();

Это хорошо, но дело в том, что эта функция, согласно документации, не работает в VC6. Я сейчас пишу под линухом, но делаю мультиплатформенное приложение, и под виндой собирался компилировать именно в VC6.

Вместо этой функции рекомендуют пользовать

Цитировать
T qFindChild ( const QObject * obj, const QString & name )

которая вроде как предназначена для компиляторов, которые не поддерживают шаблоны для методов а только для функций (ну я так понял). Таким образом, функция qFindChild() должна работать как и в gcc, так и в vc6. Но я попытался использовать её, но в линухе скомпилировать с ней не могу. Делаю, например, так

Код:
qFindChild(qApp,"editor")->set_text_to_textarea("Main text");

и выдается ошибка

Код:
ошибка: нет соответствующей функции для вызова 'qFindChild(QApplication*, const char [7])

Пока еще винду не поставил, не могу посмотреть, будет ли в ней компилиться. Поэтому не могу понять - то ли это я неправильно вызов делаю, толи функция qFindChild() компилироваться будет _только_ в vc6?

Кто-нибудь может прояснить данный вопрос?


Кстати, функция qFindChild() гораздо удобнее findChild(). Она вроде как возвращает указатель на объект, требуя только стартовую точку поиска и имя, причем тип возвращаемого указателя выставит сама. А findChild(), помимо стартовой точки и имени, требует от программиста указывать тип возвращаемого указателя. Как бы мелочь конечно, но работы добавляет.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Rcus от Октября 09, 2008, 22:39
на самом деле и qFindChild, и QObject::findChild используют одну и ту же реализацию, а точнее
Код:
    template<typename T>
    inline T findChild(const QString &aName = QString()) const
    { return qFindChild<T>(this, aName); }
Код:
template<typename T>
inline T qFindChild(const QObject *o, const QString &name)
{ return static_cast<T>(qt_qFindChild_helper(o, name, reinterpret_cast<T>(0)->staticMetaObject)); }
И в любом случае нужно будет указывать тип T прямо.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 09, 2008, 23:10
Код:
return static_cast<T>(qt_qFindChild_helper(o, name, reinterpret_cast<T>(0)->staticMetaObject));

Цитировать
используй findChild() и qobject_cast с шаблоном. имя класса можно получить из метаобъекта

:)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 10, 2008, 00:04
на самом деле и qFindChild, и QObject::findChild используют одну и ту же реализацию
И в любом случае нужно будет указывать тип T прямо.

Люди, ну скажите толком, как писать вызов qFindChild() правильно?

В документации прототип написан так

Цитировать
T qFindChild ( const QObject * obj, const QString & name )
This function is equivalent to obj->findChild<T>(name). It is provided as a work-around for MSVC 6, which doesn't support member template functions.

Нигде не вижу что тип нужно указывать. Пробовал скомпилить просто вызов функции. Вот так

Код:
qFindChild(qApp,"editor");

получаю ошибку

Цитировать
ошибка: нет соответствующей функции для вызова 'qFindChild(QApplication*, const char [7])'

и вот так пробую

Код:
qFindChild<editor>(qApp,"editor");

получаю ошибку

Цитировать
/usr/local/Trolltech/Qt-4.4.1/include/QtCore/qobject.h: In function 'T qFindChild(const QObject*, const QString&) [with T = editor]':
src/main.cpp:68:   instantiated from here
/usr/local/Trolltech/Qt-4.4.1/include/QtCore/qobject.h:408: ошибка: invalid cast from type 'int' to type 'editor'

Подключение заголовка класса editor, само собой, прописано в компилируемый cpp файл. В файл pro все используемые файлы h и cpp тоже включены.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 10, 2008, 00:38
а кто такой editor? имя класса?
если да, попробуй
Код:
qFindChild<editor*>(qApp,"editor");[code]
[/code]


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 20, 2008, 21:05
Здравствуйте!


Вот тут http://www.prog.org.ru/topic_7830_0.html (http://www.prog.org.ru/topic_7830_0.html) мы начали обсуждать как делать поиск объекта по имени. Выяснили, что надо пользоваться функциями qFindChild() или FindChild, что они должны работать рекурсивно.

Однако, практика показывает, что почему-то находятся не все объекты. Я уже скоро дыру в штанах протру, выясняя почему так.

Вот пример. В программе имеются такие объекты (вывод дерева сделан через самодельную функцию, т.к. dumpObjectInfo() dumpObjectTree() не работают http://www.prog.org.ru/topic_7824_0.html (http://www.prog.org.ru/topic_7824_0.html)). Пояснение - там где строка не начинается со слова NAME, для объекта имя не установлено.

Код:
Object tree
.NAME _layout, QMainWindowLayout
..QTimer
..QWidgetAnimator
...QTimer
.QRubberBand
.NAME editor, editor
..NAME editbold, QToolButton
..NAME editnumericlist, QToolButton
..NAME vboxLayout, QVBoxLayout
...NAME hboxLayout1, QHBoxLayout

В этом делеве нормально находится объект с именем editor, и вызывается его метод. Делается это таким кодом

Код:
 // Поиск объекта editor от корня, проходит нормально
 editor *edt;
 edt=qFindChild<editor *>(qApp,"editor");
 edt->set_text_to_textarea("Main text"); // Вызов метода найденного объекта, проходит нормально

А вот внутри этого объекта объекты уже не видятся. Пробовал так

Код:
 // Поиск кнопки на объекте editor от корня, не работает
 QToolButton *btn1;
 btn1=qFindChild<QToolButton *>(qApp,"editnumericlist");
 if(btn1!=0)
  btn1->setText("From main code for btn1");
 else
  qDebug() << "Not found editnumericlist from qApp";

и так пробовал (указатель edt найден ранее)

Код:
 // Поиск кнопки на объекте editor от объекта editor, не работает
 QToolButton *btn2;
 btn2=qFindChild<QToolButton *>(edt,"editnumericlist");
 if(btn2!=0)
  btn2->setText("From main code for btn2");
 else
  qDebug() << "Not found editnumericlist from edt";

В обоих случаях объект editnumericlist не находится в дереве через qFindChild(), хотя он там есть.

Архив простого рабочего примера прикреплен к сообщению.


Вопрос. Что делаю не так? Почему не находятся поименованные объекты? Если это имеет значение, версия Qt 4.4.1, Linux, скомпилена из исходников с дефолтными настройками.




Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 20, 2008, 21:27
непонятно почему qApp передается в функции поиска. если сделать так, то все ок
Код:
editor *edt;
 edt=qFindChild<editor *>(mainwindowpointer,"editor");
 edt->set_text_to_textarea("Main text"); // чЩЪПЧ НЕФПДБ ОБКДЕООПЗП ПВЯЕЛФБ, РТПИПДЙФ ОПТНБМШОП

 // рПЙУЛ ЛОПРЛЙ ОБ ПВЯЕЛФЕ editor ПФ ЛПТОС, ОЕ ТБВПФБЕФ
 QToolButton *btn1;
 btn1=qFindChild<QToolButton *>(mainwindowpointer,"editnumericlist");
 if(btn1!=0)
  btn1->setText("From main code for btn1");
 else
  qDebug() << "Not found editnumericlist from qApp";

 // рПЙУЛ ЛОПРЛЙ ОБ ПВЯЕЛФЕ editor ПФ ПВЯЕЛФБ editor, ОЕ ТБВПФБЕФ
 QToolButton *btn2;
 btn2=qFindChild<QToolButton *>(mainwindowpointer,"editnumericlist");
 if(btn2!=0)
  btn2->setText("From main code for btn2");
 else
  qDebug() << "Not found editnumericlist from edt";



Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 20, 2008, 21:29
сделай так и глянь, что будет в консоли
Цитировать
mainwindowpointer=&app;

 // рЕЮБФБАФУС ЧУЕ УПЪДБООЩЕ ПВЯЕЛФЩ РТЙМПЦЕОЙС
 print_object_tree();


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 20, 2008, 21:48
еще одно, не по теме, что это за мегафункция
Цитировать
char* fromQStringToChar( const QString& str )

можно ж вот эту заюзать и велосипед не изобретать
Код:
const char * qPrintable ( const QString & str ) 

или же через оператор << выводить в дебаг, т.е. так
Код:
qDebug() << "bla-bla-bla: " << 1 << 1.2;
;)

ЗЫ. я предпочитаю последний способ, ибо при помощи его очень удобно выводить и контейнеры и прочее. но это уже на любителя.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 20, 2008, 21:54
Мда, если вместо
Код:
 QApplication app( argc, argv );
 mainwindow win;
 mainwindowpointer=&win;

Сделать
Код:
 QApplication app( argc, argv );
 mainwindow win;
 mainwindowpointer=&app;

или, что тоже самое, сделать mainwindowpointer=qApp;, то дерево объектов (которое строится начиная с указателя mainwindowpointer) будет вот такое

Код:
Object tree
.QGuiEventDispatcherGlib
.NAME plastique, QPlastiqueStyle
.QSessionManager
.QXIMInputContext


то есть относительно объекта app (или qApp) невозможно найти editnumericlist. Возможно, это и есть ответ на вопрос. НО! Почему тогда работает код

Код:
 // Поиск объекта editor от корня, проходит нормально
 editor *edt;
 edt=qFindChild<editor *>(qApp,"editor");
 edt->set_text_to_textarea("Main text"); // Вызов метода найденного объекта, проходит нормально

?

Ведь в поддереве объекта qApp, как мы выяснили (в распечатке Object tree выше), нет объекта editor!


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 20, 2008, 22:16
Хорошо, давайте отвлечемся :)

еще одно, не по теме, что это за мегафункция
Цитировать
char* fromQStringToChar( const QString& str )

можно ж вот эту заюзать и велосипед не изобретать
Код:
const char * qPrintable ( const QString & str ) 

Это вопрос сложности синтаксиса языка C/C++, не предназначенного для восприятия простым человеком. Вот еслиб прототип был хотябы такой

Код:
char *qPrintable(QString str)

то я бы не задумываясь стал использовать эту функцию.


или же через оператор << выводить в дебаг, т.е. так
Код:
qDebug() << "bla-bla-bla: " << 1 << 1.2;

ЗЫ. я предпочитаю последний способ, ибо при помощи его очень удобно выводить и контейнеры и прочее. но это уже на любителя.

Если вы предпочитаете последний способ, то вы очевидно знаете его особенности.

1. Если выводится строка QString, то она будет заключена в кавычки.
2. На месте оператора "<<" обязательно появляется пробел.

Например
Код:
QString name="Vasya";
qDebug() << "Name is " << name;
выведет
Код:
Name is  "Vasya"

(обратите внимание на два пробела в результате)

Таким образом, в выводимой строке получаем неубираемые кавычки, а из-за обязательного пробел на месте оператора "<<" вы не можете вывести строку, в которой что-то будет написано слитно.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 20, 2008, 22:23
Цитировать
Это вопрос сложности синтаксиса языка C/C++, не предназначенного для восприятия простым человеком. Вот еслиб прототип был хотябы такой

Code:
char *qPrintable(QString str)

то я бы не задумываясь стал использовать эту функцию.
не понял ход мысли. какое вызывает недопонимание функции с константной ссылкой?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 20, 2008, 23:47
мдя...


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 00:42
Код:
Object tree
.QGuiEventDispatcherGlib
.NAME plastique, QPlastiqueStyle
.QSessionManager
.QXIMInputContext

то есть относительно объекта app (или qApp) невозможно найти editnumericlist. Возможно, это и есть ответ на вопрос. НО! Почему тогда работает код

Код:
 // Поиск объекта editor от корня, проходит нормально
 editor *edt;
 edt=qFindChild<editor *>(qApp,"editor");
 edt->set_text_to_textarea("Main text"); // Вызов метода найденного объекта, проходит нормально

?

Ведь в поддереве объекта qApp, как мы выяснили (в распечатке Object tree выше), нет объекта editor!

Таки никто не знает? Я уж думаю, может дерево объектов не все обрабатывается при распечатке, может там всетаки есть еще объекты? Но проверить не могу из-за неработоспособности dumpObjectInfo() и dumpObjectTree(). У кого эти методы работают, может хотя бы показать дерево от объекта win и от объекта app?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 21, 2008, 10:04
эта конструкция возвращает 0
Код:
editor *edt;
edt=qFindChild<editor *>(qApp,"editor");
edt->set_text_to_textarea("Main text")
для проверки выведите в дебаг переменную или же QPointer заюзайте.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 10:22
эта конструкция возвращает 0
Код:
editor *edt;
edt=qFindChild<editor *>(qApp,"editor");
edt->set_text_to_textarea("Main text");
для проверки выведите в дебаг переменную или же QPointer заюзайте.

Удивительно! Конструкция

Код:
edt=qFindChild<editor *>(qApp,"editor")

действительно присваивает адрес 0 указателю edt. Но при этом нормально работает вызов метода

Код:
edt->set_text_to_textarea("Main text");

так как в консоли появляется строка

Код:
In editor method set_text_to_textarea() set text  "Main text"

Как же это так происходит???


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 21, 2008, 10:48
гы, крута, вот такая хрень пашет и не падает
Код:
editor *edt = 0;
edt->set_text_to_textarea("Main text");
;D

че-от, где-то я не замечаю  ???


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Tonal от Октября 21, 2008, 11:15
Удивительно! Конструкция
Код:
edt=qFindChild<editor *>(qApp,"editor")
действительно присваивает адрес 0 указателю edt. Но при этом нормально работает вызов метода
Код:
edt->set_text_to_textarea("Main text");
Как же это так происходит???
И что тут удивительного? Это UB - значит можно произойти всё что угодно. :)
А если объяснять на пальцах - метод это обычная функция, с дополнительным скрытым аргументам, в котором передаётся this. Если этот аргумент не используется, то всё равно что там передаётся. :)
Вот если бы метод был виртуальным, то ты бы сразу получил AV. :)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 21, 2008, 11:18
да уж точно. в методе инфы о классе нет, вот он и срабатывает как статическая функция.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 21, 2008, 11:50
Это вопрос сложности синтаксиса языка C/C++, не предназначенного для восприятия простым человеком. Вот еслиб прототип был хотябы такой

Код:
char *qPrintable(QString str)

то я бы не задумываясь стал использовать эту функцию.

А что вас смущает?

ЗЫ: Передача QString и других шаровых классов по значению, это дурной тон программирования на Qt, и С++ здесь абсолютно непричем. Правильно будет юзать константную ссылку.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 15:53
используй findChild() и qobject_cast с шаблоном. имя класса можно получить из метаобъекта

Код:
return static_cast<T>(qt_qFindChild_helper(o, name, reinterpret_cast<T>(0)->staticMetaObject));

А можно подробнее про этот ребус? Что из чего преобразуется?

Желательно, кусочек кода с реализацией функции qt_qFindChild_helper() и функции, в которой используется этот хитрый return (и как ее вызывать).

Особенно интересует третий параметр функции qt_qFindChild_helper(), что это за переменная такая? Какой у нее будет тип? Для чего она нужна? Это переменная-пустышка, через которую только передается тип искомого объекта, который будет подставлен при вызове qFindChild()?

Вы пишите "имя класса можно получить из метаобъекта". Что нам это даст? При поиске через FindChild()/qFindChild() в любом случае нужно заранее знать тип искомого объекта, т.е. просто найти объект по имени не получится (если не пользоваться самодельной функцией поиска). Кроме того, неясно что нам может дать строка с именем класса. Всеравно мы ведь не можем воспользоваться значением полученной строки в шаблоне.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 21, 2008, 16:06
а если в шаблоне задавать QWidget и имя объекта, а не конкретный типя. хотя затем все равно нужно делать приведение к необходимому типу, так что тип в шаблон нужно задавать реальный.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Alex Custov от Октября 21, 2008, 16:24
Код:
    // создаём виджет и три кнопки на нём
    W *w = new W;

    // находит и выводит "QPushButton(0x80904b0, name = "B3")"
    qDebug() << qFindChild<QPushButton *>(w, "B3");


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Alex Custov от Октября 21, 2008, 16:27
findChild() ищет рекурсивно, или только объекты, являющиеся children для обрабатываемого объекта ( в вашем случае qApp) ?

рекурсивно.

Вообще, скачайте исходники Qt. Очень помогает в некоторых ситуациях.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Alex Custov от Октября 21, 2008, 16:32
Я не понимаю почему ты постоянно используешь объект QApplication в функциях поиска?? Виджеты не являются детьми QApplication, поэто искать виджет по имени через qApp не имеет смысла. Его искать нужно через toplevel виджет, на котором он расположен (если точно не знаешь прямого родителя), или через прямого родителя.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 21, 2008, 16:34
просто изначально кто-то показал пример с qApp вот и погнал его юзать :)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 17:13
Это вопрос сложности синтаксиса языка C/C++, не предназначенного для восприятия простым человеком.

какое вызывает недопонимание функции с константной ссылкой?
что вас смущает?

Понимаете, есть такая вещь - семантика называется. Семантика, говоря кратко - это представление смысла. Любой язык программирования (как система обозначений) через свой синтаксис выражает семантику задачи. И хорошим тоном считается такая запись алгоритма, когда семантика задачи выражена синтаксисом напрямую. Код, написаный по такому принципу, прост для понимания и последующего сопровождения.

Возьмем к пример нашу функцию qPrintable(). Задача этой функции - преобразовать Qt строку QString в стандартную сишную строку. Заметтьте, ни о каких константных указателях речи не идет. Так же как и не идет речи ни о каких адресах объектов для неявного получения ссылки на исходную строку.

Фраза "преобразовать Qt строку QString в стандартную сишную строку", в языке C/C++ с использованием Qt, естественным образом выражается прототипом
Код:
char *qPrintable(QString str)

а если бы в C/C++ изначально бы были типы массивов (как это сделано в паскале), то можно былоб выразить еще понятнее, например
Код:
array of char qPrintable(QString str)

Вот и сравните то, что написано выше, с прототипом вида
Код:
const char * qPrintable ( const QString & str )

О чем этот прототип говорит? Как минимум о том, что просто сформулированная задача будет решаться какими-то странными обходными путями, причем понимание того, как нужно подготовить входные данные для такого "решения" и как взять выходные данные, целиком и полностью ложится на программиста. Таким образом, использование этого прототипа уводит мышление программиста из предметной области решаемой задачи в предметную область реализации машинного языка. Это отвлекает внимание, отбирает время, а так же заставляет программиста быть сконцентрированным при использовании пустякой впринципе функции, что утомляет и создает другие негативные последствия.

ЗЫ: Передача QString и других шаровых классов по значению, это дурной тон программирования на Qt

Да это просто щастье, что в Qt есть нормальные строки, а не указатели на байтовые массивы. Теперь осталось, чтобы до разработчиков дошло, что надо программировать не "на языке" а "с использованием языка". Удивительное дело - выразительные средства языка уже позволяют писать программы так, как они представляются в объектах реального мира. Так нет же, всеравно имея такие средства, пишут по старинке, ставя во главу угла опимизацию в ущерб понятности. Можно еще понять, когда дело касается гигабайтных объемов, когда копия данных делается медленно и места мого занимает. Но когда речь идет о текстовых строках, оптимизация работы через указатели со всеми воможными побочными эффектами мне непонятна.

Вон даже у сантехников написано

Цитировать
Побочные эффекты, связанные с использованием указателей - самая большая проблема для компиляторов с языков C/C++. Поэтому, если время исполнения программы для Вас является важным фактором, постарайтесь избегать использования указателей при вычислениях. Индексирование массивов лучше поддается оптимизаци, чем обращение по указателю. Например:

for( int i=0; array; i++ ) foo(array); // рекомендуемый подход

for( T* p=array; *p; p++ ) foo(*p); // старайтесь избегать

http://ru.sun.com/developers/sunstudio/articles/amdopt_ru.html (http://ru.sun.com/developers/sunstudio/articles/amdopt_ru.html).


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 17:21
Я не понимаю почему ты постоянно используешь объект QApplication в функциях поиска?? Виджеты не являются детьми QApplication, поэто искать виджет по имени через qApp не имеет смысла. Его искать нужно через toplevel виджет, на котором он расположен (если точно не знаешь прямого родителя), или через прямого родителя.

Это в предыдущей теме http://www.prog.org.ru/topic_7830_0.html (http://www.prog.org.ru/topic_7830_0.html) такой совет дали. Изначально поиск шел от mainwindow. И сейчас я делаю поиск от mainwindow, ибо когда посмотрел дерево от qApp

Цитировать
Object tree
.QGuiEventDispatcherGlib
.NAME plastique, QPlastiqueStyle
.QSessionManager
.QXIMInputContext


понял что ничего нужного это дерево не содержит :).


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Rcus от Октября 21, 2008, 17:34
Виновен :) Только потом понял что приведенный мною пример не работает (виджеты не могут иметь в parent не QWidget*), меня оправдывает только то что для консольных приложений подход с единым предком работает

P.S. А теперь пофлеймим :) прототип qPrintable очень информативен на самом деле, "const QString&" означает что функция не изменяет параметр (кстати в Object Pascal/Delphi тоже рекомендуется передавать строки с указанием const чтобы избежать операций со счетчиком ссылок), "const char*" указывает на неизменяемость результата (при возврате по стеку вызовов память выделенная будет освобождена, поскольку результат указывает на внутреннюю структуру временного объекта). Помоему ничего плохого нет в том чтобы показать семантику функции и защитить программиста от ошибок при помощи синтаксиса языка.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 21, 2008, 17:39
2 xintrea: про qPrintable написано много, смысла - 0. Вы понимаете разницу между QString str и const QString & str? Перечитайте ещё раз мой предыдцщий пост: в Qt не принято передавать ПО ЗНАЧЕНИЮ данные шаровых типов.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 21, 2008, 17:54
начну с того, что в сях вообще нет типа "строка"
я сейчас под впечатлением того длинного поста выше...и цивилизованно выражаться могу лишь сдерживаясь.
предлагаю прекратить этот бредовый флэйм и читать книжки/документацию...читать, читать и снова читать...
в противном случае искать объект по имени будем в /dev/null...


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 18:24
рекурсивно.

Вообще, скачайте исходники Qt. Очень помогает в некоторых ситуациях.

Это уже обсудили выше.

В данный момент интересуют комментарии к

Цитировать
используй findChild() и qobject_cast с шаблоном. имя класса можно получить из метаобъекта

Код:
return static_cast<T>(qt_qFindChild_helper(o, name, reinterpret_cast<T>(0)->staticMetaObject));

Видимо человек знает, как преобразовывать строку с названием типа (именем класса) непосредственно в тип. Если это так, то хочется подробностей.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 21, 2008, 20:25
бля, какое название класса в тип?
Цитировать
T QObject::findChild ( const QString & name = QString() ) const
Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. Omitting the name argument causes all object names to be matched. The search is performed recursively.
If there is more than one child matching the search, the most direct ancestor is returned. If there are several direct ancestors, it is undefined which one will be returned. In that case, findChildren() should be used.
This example returns a child QPushButton of parentWidget named "button1":
         QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
перевести?

тип в данном случае - это Т...и его (тип) мы указываем явно в шаблоне. тяжко посмотреть код qt_qFindChild_helper?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 21, 2008, 21:49
какое название класса в тип?

Ну, ведь есть возможность получить из типа строку с названием типа (или класса). Например, это можно сделать через поле name оператора typeid, или через metaObject().className(). Почему бы тогда не иметь возможность обратного действия -  например, подставлять в шаблон тип из строки? Ведь в C++ возможна динамическая типизация.

Понятно, что я размечтался, но хочется иметь инструменты преобразования в обе стороны.


Цитировать
T QObject::findChild ( const QString & name = QString() ) const
Returns the child of this object that can be cast into type T and that is called name, or 0 if there is no such object. Omitting the name argument causes all object names to be matched. The search is performed recursively.
If there is more than one child matching the search, the most direct ancestor is returned. If there are several direct ancestors, it is undefined which one will be returned. In that case, findChildren() should be used.
This example returns a child QPushButton of parentWidget named "button1":
         QPushButton *button = parentWidget->findChild<QPushButton *>("button1");
перевести?

Уже ненадо. Хотя, отправьте пожалусто перевод сюда http://www.crossplatform.ru/documentation/qtdoc4.3/index.php (http://www.crossplatform.ru/documentation/qtdoc4.3/index.php)


тип в данном случае - это Т...и его (тип) мы указываем явно в шаблоне. тяжко посмотреть код qt_qFindChild_helper?

Да, тяжко, ибо вы не сказали, что это вообще за функция и где ее брать. Я проверил ее в QtAssistant, такой функции нет. Поэтому подумал, что это функция в какой-то вашей программе, и вы приводите пример вызова. Откуда мне знать, что функция эта оказывается лежит в исходниках Qt в /src/corelib/kernel/qobject.cpp?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 21, 2008, 21:53
Цитировать
Откуда мне знать, что функция эта оказывается лежит в исходниках Qt в /src/corelib/kernel/qobject.cpp?

подебажить  ;)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 22, 2008, 01:08
grep? поиск венды?

две ветки по изобретению велосипедов и исследованиям примитивов...страница бессмысленнейшего флейма на тему константных указателей...
извиняюсь, но весь этот бред отправляется в "кандидаты". повторяю в стотысячный раз: читать документацию, читать книги по кутэ и плюсам, гуглить и снова читать!

зы. и с таким-то уровнем осведомлённости ещё поносишь разработчиков smb4k? на лоре я предупредил - не удивляйся, если однажды смф тебя не опознает...


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 13:33
grep? поиск венды?

две ветки по изобретению велосипедов и исследованиям примитивов...страница бессмысленнейшего флейма на тему константных указателей...
извиняюсь, но весь этот бред отправляется в "кандидаты". повторяю в стотысячный раз: читать документацию, читать книги по кутэ и плюсам, гуглить и снова читать!

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

Порекомендую для прочтения следующие книги:

  • Одинцов И.О. Профессиональное программирование. Системный подход. - БХВ-Петербург.
  • Макконнелл С. Совершенный код. - Микрософт пресс.
  • Керниган Б., Пайк Р. Практика программирования. Простота, ясность, общность. - Addison Wesley
  • Бобровский С. Программная инженерия. - СПб. Питер

эти книги так сказать, отрезвляют.

зы. и с таким-то уровнем осведомлённости ещё поносишь разработчиков smb4k? на лоре я предупредил - не удивляйся, если однажды смф тебя не опознает...

Да, я поношу разработчиков smb4k на лоре, ибо мой уровень осведомленности мне это позволяет. Единственное мерило оценки проекта - это работает проект так как нужно (прозрачно для пользователя, без гемора) или нет. Если бы проект действительно так работал, он бы уже давно был неотъемлемой частью KDE, как поддержка ext2/3 в ядре линуха. Пока мы этого не наблюдаем. Значит, не все так гладко и требования юзабельности до сих пор не выполнены, даже такие непритязательные, как и все в линухе. Скажу больше - у меня хоть устанавливай smb4k, хоть деинсталлируй - в kde-шных программах есть возможность обращаться к smb ресурсам. А вот в гимпе, в инкскейпе, в опере, с сетевыми ресурсами не поработаешь. В винде - поработаешь (да-да, в винде в которой нет никакого "системного" уровня, в которой тоже только прозрачное автомонтирование). А в линухе - не поработаешь. Даже при наличие smb4k.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 22, 2008, 13:48
> порекомендую вам прекращать читать ... Порекомендую для прочтения
дык, прекращать читать книги или всё же читать?
если тебе непонятна декларация const char*, прекращай читать про "совершенный код"...

> уже давно был неотъемлемой частью KDE, как поддержка ext2/3 в ядре линуха
угу-угу, сделаем самбу неотъемлемой частью ядра, а гуишку для самбы - неотъемлемой часть КДЕ. понимаешь что говоришь? может ещё вендовый загрузчик сделать основой grub'а или запихнуть вайн в кернел-левел?
в общем, сравниваешь х?й с пальцем.
почему у меня адекватно работает и раб smb://, и самбочка, а у тебя - нет? может мне тоже чего-нибудь почитать? про идеальную настройку лялиха у тебя нет книг?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 16:25
> порекомендую вам прекращать читать ... Порекомендую для прочтения
дык, прекращать читать книги или всё же читать?

По правилам сетикета, цитаты нужно давать полностью, как минимум до знака препинания. Правильная цитата звучит так: "В свою очередь порекомендую вам прекращать читать книги по кутэ и плюсам".


если тебе непонятна декларация const char*, прекращай читать про "совершенный код"...

Конструкция понятна, да только чтобы ее понять - отвлекаешься от задачи, лезешь в справочник, выясняешь что к чему, пишешь тестовый код чтоб удостовериться, что правильно понял, возвращаешься к задаче. Проблема в том, что конструкция настолько неудобна, что точно и недвусмысленно описать, что при ее использовании происходит, не так то просто. Кстати, давно ищу книжку, в которой бы нормально с точки зрения организации памяти и машинных кодов было написано, что такое указатель, что такое ссылка. В свое время я даже декомпилировал коды примеров чтобы понять, что на самом деле происходит. Давайте, я переборю себя, и загляну в книжку по плюсам. Что видим?

(http://i.piccy.kiev.ua/i2/0b/36/744b81b16752baf7139821aa86d8.png)
http://i.piccy.kiev.ua/i2/0b/36/744b81b16752baf7139821aa86d8.png (http://i.piccy.kiev.ua/i2/0b/36/744b81b16752baf7139821aa86d8.png)

Вы считаете такую путаницу нормальной? Я нет.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 22, 2008, 16:27
не используйте С++. а раз уж используете, то вы обязаны это знать.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 22, 2008, 16:42
Вы считаете такую путаницу нормальной? Я нет.

То что вы этого не понимаете неозначает, что это некому ненужно. Извените, но я немогу уловить нималейшей связи между семантикой функции qPrintable и приведеной вами страницы про модификатор const из книги  ???


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: BRE от Октября 22, 2008, 17:13
Вы считаете такую путаницу нормальной? Я нет.
2 xintrea
Все что ты пишешь про const, сводится к фразе: Я не могу понять как пользоваться const, поэтому все кто его использую - дураки. Глобально.  ;D

Вот смотри, если бы qPrintable было бы описано, как char* qPrintable(...), то обязательно нашелся бы умник, который бы сделал ПРИМЕРНО так:
Код:
char *p = qPrintable( str );
p[10345] = 0;
Как ты думаешь, к чему бы это привело?
А так тебе дадут по рукам еще на этапе компиляции.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 22, 2008, 18:14
судя по размеру скана выше, могу предположить, что это какой-то карманный справочник...и примеры там призваны _прояснить_ ситуацию, а не доказывать сложность конструкции. не, не проясняют?

я плюсы начинал учить лет в 15 по книжке самостоятельно (преподы в школе знали только паскаль). что было непонятно, перечитывал, пока не приходило понимание, т.к. писать методом тыка считаю неприемлемым.
и о чудо! - спустя столько лет, пусть я долгое время вообще и не писал на плюсах, ну не запутывает меня const char* и всё тут!


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 19:40
Цитата: BRE link=topic=7830.msg41169#msg41169

2 xintrea
Все что ты пишешь про const, сводится к фразе: Я не могу понять как пользоваться const, поэтому все кто его использую - дураки. Глобально.  ;D

Ну, ненадо говорить за другого человека.

Чего я действительно не могу понять, так это смысла защищать результаты вычислений.

Понятно, что (возможно) нужно защищать передаваемые параметры, чтоб программер был спокоен, что с его данными ничего не случится. Хотя, такое поведение должно быть у любой функции по умолчанию (если не требуется, конечно, целенаправленного изменения переданных данных). И показывать const в параметре - это, извините, моветон. Конечно, при передачи через ссылку показывать const нужно, типа "чувак, ты конечно ссылку передаешь, но небаись, это только для доступа к преобразуемой строке, мы с ее содержимым по известному нам адресу ничего делать не будем". Но зачем громаздить такие понятийные слои, когда можно передать по значению? Да, с точки зрения оптимизации надо кувыркаться с указателями ( const QString & str ). А с точки зрения передачи смысла, для отображения "что делает функциия" надо писать ( String  str ) и никак иначе. В нынешних реалиях от языка требуется именно вторая воможность, чтобы API библиотек и код программы отображал в явном виде действия над данными, а не запутывал лишний раз программиста.


Цитата: BRE link=topic=7830.msg41169#msg41169

Вот смотри, если бы qPrintable было бы описано, как char* qPrintable(...), то обязательно нашелся бы умник, который бы сделал ПРИМЕРНО так:
Код:
char *p = qPrintable( str );
p[10345] = 0;
Как ты думаешь, к чему бы это привело?
А так тебе дадут по рукам еще на этапе компиляции.

Скажу по секрету, что обязательно найдется умник, который сделает так

Код:
char *p = (char *)qPrintable( str );
p[10345] = 0;

потому что полученную строку ему надо еще как-то преобразовывать. Объясните, для чего защищать через const результат вычисления?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 20:05
судя по размеру скана выше, могу предположить, что это какой-то карманный справочник...и примеры там призваны _прояснить_ ситуацию, а не доказывать сложность конструкции.

Да, это такой небольшой карманный справочник, на 500 страниц.

я плюсы начинал учить лет в 15 по книжке самостоятельно (преподы в школе знали только паскаль). что было непонятно, перечитывал, пока не приходило понимание, т.к. писать методом тыка считаю неприемлемым.
и о чудо! - спустя столько лет, пусть я долгое время вообще и не писал на плюсах, ну не запутывает меня const char* и всё тут!

Коль всеравно флеймим... :)

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


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 22, 2008, 20:06
Пастор уже раза два говорил: QString - шаренный класс. const QString& позволит работать с объектом быстрее, т.к. под объект не придётся создавать глубокую копию объекта - можно работать с объектом напрямую. а const позволяет быть уверенным, что объект вернётся из вызова таким же, каким ушёл - без изменений.

надеюсь, я доходчиво объяснил. не будем к этому возвращаться?

Цитировать
Скажу по секрету, что обязательно найдется умник, который сделает так
Код:
char *p = (char *)qPrintable( str );
p[10345] = 0;
отбить такому умнику руки! по аналогии с электрощиком, на котором написано "не влезай - убьёт" (и ведь убьёт же), а он всё-равно лезет.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 22, 2008, 20:07
> не запутывает меня LEA инструкция и всё тут
асм не запутывает, а const char* выше понимания? не верю...


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 22, 2008, 20:09
Но зачем громаздить такие понятийные слои, когда можно передать по значению?

    Как зачем??? Вы понимаете сам процесс передачи по значению? Что при этом происходит? А если передаеться огромный объем данных? (Ответ домыслите сами)

Да, с точки зрения оптимизации надо кувыркаться с указателями ( const QString & str ).

Это ссылка, а не указатель!

А с точки зрения передачи смысла, для отображения "что делает функциия" надо писать ( String  str ) и никак иначе. В нынешних реалиях от языка требуется именно вторая воможность, чтобы API библиотек и код программы отображал в явном виде действия над данными, а не запутывал лишний раз программиста.

В Qt для шаровых классов передача по значению и по константной сылке равнозначны впринципе (копирования не происходит). Но... принято использовать константный указатель (так немного быстрее, непроисходит инкремент\дикремент счетчика ссылок). Я уже про это писал. Вы знакомы с работой шаровых классов? Почитайте...

Скажу по секрету, что обязательно найдется умник, который сделает так

Код:
char *p = (char *)qPrintable( str );
p[10345] = 0;

потому что полученную строку ему надо еще как-то преобразовывать. Объясните, для чего защищать через const результат вычисления?


Ну это он уже сам нарываеться на проблему. Кто ему доктор что он так сделае? Результат нужно защищать через конст, чтобы не иметь возможноти его модификации, т.к. неизвесно сколько буде валиден возвращаемый указатель Нужно модифицировать - копируй.

ЗЫ: В случае с qPrintable, указатель p будет невалиден после вызова функции:

Код:
char *p = (char *)qPrintable( str );
p[10345] = 0;   //указател невалиден!

Это также относиться к таким мтодам QString, как toLocal8Bit, toAscii, и это неотноситься к С++. Это ньюансы Qt.


А если не секрет, на чем вы писали до С++, Pascal?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 22, 2008, 20:21
да уж, надо учить плюсы срочно и не задавать "умных" вопросов.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 22:50
> не запутывает меня LEA инструкция и всё тут
асм не запутывает, а const char* выше понимания? не верю...

Ну уж поверьте. Разберитесь с асмом, и вы поймете насколько в нем все просто. Главное понять, как устроен микропроцессор - что такое регистры общего назначения, адресные регистры, флаги, стек, сегменты памяти.

Аналог "ссылки" реализуется в ассемблере очень просто:

Код:
; Загрузить в регистр AL значение, расположенное по некоторому адресу (в регистре BX лежит адрес)
MOV AL, [BX]

Но чаще всего адрес высчитывается не напрямую, а несколькими командами. Тогда используется конструкция
Код:
; Загрузить в регистр SI некий хитро вычисленный адрес
LEA SI, [BX+DI]

; Загрузить в аккумулятор значение байта памяти, расположенного по адресу, указанному в регистре SI.
MOV AL, [SI]

Для последовательности байт (массивы), поиск символа:
Код:
LEA DI,[BX].filename ; Загружаем в регистр DI некий адрес начала строки
CLD                  ; При каждой итерации, DI будет увеличиваться (сканирование вперед)
MOV CX,100           ; В регистр CX загружаем длину строки (100 байт)
MOV AL,'a'           ; какой символ будем искать

; А вот и сама команда поиска
; Пробегаем область памяти, начиная с ячейки, адрес которой лежит в DI
; Проверяем, не содержится ли в ячейке символ 'a'
; После проверки каждой ячейки DI автоматически увеличится на единицу
; Будет обработано количество ячеек, указанное в CX
; После проверки каждой ячейки CX автоматически уменьшится на единицу
; Поиск либо завершится досрочно, если будет встречен символ 'a'
; либо пробежит все 100 байт
REPNE SCASB

JNE FIN              ; Ежели ничего не найдено, прыгаем на код, который обрабатывает ситуацию что ничего не найдено
...                  ; А здесь код, который обрабатывает ситуацию что символ найден

Весь ассемблер - это по сути оперирование регистрами и командами, которые могут взять данные из одного адреса памяти, и положить данные в нужный адрес памяти. Все. И никаких тебе "ссылок" и "указателей". Точнее, их можно реализовать (и указатель на указатель на указатель), но при реализации видно, как что конструируется. А так же нет синтаксических залипух типа "* как тип указателя", "* как разыменовывание указателя", "& как ссылка", "& как адрес" (какой садист до этого додумался?), "**", "***", ".", "->" и т.д.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 22, 2008, 22:55
а почему вы тогда на плюсах пишите? пишите на ассемблере , если там все так просто и "наглядно".   ;)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 23:07
а почему вы тогда на плюсах пишите? пишите на ассемблере , если там все так просто и "наглядно".   ;)

Вы про слои абстракции что-нибудь слышали?


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: spirit от Октября 22, 2008, 23:16
если честно, то меня эта тупая и бессмысленная тема уже утомила. то что вы поститет отностится к выражениям по типу "с точки зрения банальное эрудиции....". в общем читать, читать и еще раз читать как говорит Константин и не морочить головы людям.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 22, 2008, 23:41
> Разберитесь с асмом
асм я пытался учить ещё до плюсов, потом пришлось всё вспоминать заново в универе, сейчас вряд ли смогу написать что-то осмысленное целиком на асме, но примитивы не забываются - это как езда на велосипеде...


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 22, 2008, 23:54
Результат нужно защищать через конст, чтобы не иметь возможноти его модификации, т.к. неизвесно сколько буде валиден возвращаемый указатель

Тут вы меня пугаете... Как так неизвестно, сколько будет валиден возвращаемый указатель? То есть, если указатель защищен const, то известно? А если не защищен const, то неизвестно? Как то это странно все, проясните пажалусто.


А если не секрет, на чем вы писали до С++, Pascal?

Ничего особенного. Как уже выяснили, на ассемблере писал. Фокс, 1С по работе. PHP для интереса. Ну ActionScript2 для интереса. Паскаль один раз использовал как алгоритмический язык, можно было на любом другом языке алгоритм реализовывать (делал дихотомайзер).

Как оказалось, чтобы начать понимать C++, вначале легче понять ООП в PHP или в ActionScript, а уже потом в C++. И я не один такой, мы с парой перцев про это говорили, у них такая же ситуация. Хотя, сложность C/C++ не в инструментах ООП, а в этих вот указателях и ссылках, которые являются постоянным источником проблеммы, причем не только у меня, а и у мегапрофи, проверено. И сложности добавляет неоднозначность синтаксиса.

Зачем для разных действий (* как ссылочный тип), (* как разыменовывание указателя), (& как адрес), (& как ссылка), сделали одинаковое обозначение? Мне непонятно.

Так же непонятно, зачем для одного и того же действия сделали разное обозначение (. доступ к члену если работаем с объектом), (-> доступ к члену если работаем с ссылкой на объект). Зачем так извратно?

Понятно, что это проблемы роста языка, "обвешивание" функционалом "на лету". Но ведь были другие пути, более удобные для конечного использования. Зачем было делать такие залипухи, если сразу еще при проектировании было ясно - получится хреново! Сами путаться будете, и неофитам хренобъясните что к чему.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 23, 2008, 00:07
ООП в пыхпыхе? :))

> Зачем для разных действий (* как ссылочный тип), (* как разыменовывание указателя), (& как адрес), (& как ссылка), сделали одинаковое обозначение? Мне непонятно.

они ж ставятся с разных сторон операнда - один раз запомнить что есть что - и никаких проблем уже не будет...как и с const'ом )
с "." и "->" тоже всё предельно ясно - член объекта и член объекта по указателю соответственно...

> если сразу еще при проектировании было ясно - получится хреново!
это я уже считаю оскорблением!


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: BRE от Октября 23, 2008, 00:12
[off]  ;D Вот и дожили... Знанием асма снова начали гордится.
Первый освоенный асм от процессора 6502. Была такая машина Commodore 64, было это в 1988 г. Помню его до сих пор, эх были времена, какие вещи делали, как код оттачивали... Потом 8086, 80286, 80386, 80486. Потом пошли пентимумы, и писание на голом асме потеряло смысл, сравниваться с оптимизаторами стало не реально.
Теперь идут жабы, делфи и всякая такая фигня. Прогресс блин.
[on]

2 xintrea
Не знаю правда для чего были приведены примеры на асме, но....

Код:
const char *qPrintable( const QString &str );

Любой программист смотря на это определение и не глядя на код самой функции отмечает для себя, что те данные на которые возвращается указатель, модифицировать нельзя. Это наглядно и понятно.
Теперь по поводу параметра. С точки зрения эффективности лучше передать ссылку на объект, чем сам объект, и это не прихоть разработчиков Qt, а требование эффективности. Почитай чем отличаются передача ссылки от передачи объекта в функцию или дисассемблируй, думаю все стенет ясно.  ;)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: BRE от Октября 23, 2008, 00:17
Как оказалось, чтобы начать понимать C++, вначале легче понять ООП в PHP или в ActionScript, а уже потом в C++.
Я учил после C, и ты знаешь не путаюсь ни в чем. Надо ActionScript посмотреть...

И я не один такой, мы с парой перцев про это говорили, у них такая же ситуация. Хотя, сложность C/C++ не в инструментах ООП, а в этих вот указателях и ссылках, которые являются постоянным источником проблеммы, причем не только у меня, а и у мегапрофи, проверено. И сложности добавляет неоднозначность синтаксиса.
Ты по меньше общайся с такими МЕГАПРОФИ.  ;)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 23, 2008, 01:26
ООП в пыхпыхе? :))

Ну да. Декомпозиция задачи (классы), инкапсуляция, наследование (кроме множественного). Все это в PHP есть, и для стартового понимания хорошо подходит.


> Зачем для разных действий (* как ссылочный тип), (* как разыменовывание указателя), (& как адрес), (& как ссылка), сделали одинаковое обозначение? Мне непонятно.

они ж ставятся с разных сторон операнда - один раз запомнить что есть что - и никаких проблем уже не будет...как и с const'ом

Ну вот давайте посмотрим на прототип в QtAssistant

Код:
const char * qPrintable ( const QString & str )

Кутешники хитрые ребята, и написали так, что ясности нет, чему принадлежат * и &, ибо синтаксис позволяет.

И вот товарищ BRE решил объяснить что к чему (это похвально, без издевки), и написал так:

Код:
const char *qPrintable( const QString &str );

Но вот что-то мне подсказывает, что правильно было бы написать так:

Код:
const char *qPrintable( const QString& str );

ведь у нас в аргументе ссылка, а не адрес.


Налицо проблема - куда прилеплять эти синтаксические элементы (*, &) для правильного описания выполняемых кодом действий?

Ведь впринципе код

Код:
const char * qPrintable()
const char* qPrintable()
const char *qPrintable()

const QString & str
const QString& str
const QString &str

при компиляции даст одинаковый результат (хотя с & надо еще проверить..). Но тогда встает вопрос, что является операндом, относительно которого можно ориентироваться "слева" или "справа"?

Код:
char*         ?
*qPrintable() ?
QString&      ?
&str          ?

Если бы синтаксис не разрешал использовать как попало * и &, было бы гораздо легче. Но мы имеем то, что имеем. Посему вопрос открыт - какое мнемоправило использовать для вычленения операнда? Оно просто необходимо, чтобы после определения операнда уже думать, куда лепить * или &.


> если сразу еще при проектировании было ясно - получится хреново!
это я уже считаю оскорблением!

Не принимайте все так близко к серццу.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: denka от Октября 23, 2008, 05:58
2 xintrea
Почитал тут два ваших топика и решил написать. Первое впечетление шок. Щас не знаю или мне дико ржать или же плакать. Ясно точно одно вам следует приостановить какие либо разработки и читать про указатели и ссылки(возможно еще про что-то). В топике http://www.prog.org.ru/topic_7895_15.html (http://www.prog.org.ru/topic_7895_15.html) вы писали про семантику языка, так вот семантики С++ вы не знаете. Вобще какая разница возле чего стоит '&' или '*'(сдесь у меня вобще чувство что вы писали на Fortrane), главное в каком месте мы используем их. Так вот определение того что у перед нами указатель( или ссылка), а не разыменовывание указателя( или взятие адреса) - это использование его в объявлениях переменных и ф-ций.
Раз уж вы так любите практику давайте расмотрим несколько примеров:
Код:
char * string = "xintrea вы должны учить С++!";
char * foo();
char ** foo2();
char (*f)();
char *(*f2)();
char * p1, p2;
Прежде всего хочу обратить ваше внимание что здесь мы объявляем переменные и ф-ции. Поэтому использование символа '*' означает объявления указателя на что-то. В первом случае мы имеем указатель на область памяти котрую нужно интепритировать как символ или проще говоря у нас здесь "С-строка". Во втором - мы имеем ф-цию которая возвращает указатель на char. В 3 - ф-цию которая возвращает указатель на указатель(В С к примеру так возвращали массивы строк). В 4 у нас указатель на ф-цию, причем заметьте понимание того, что у нас указатель на ф-цию приходит не из местоположения *, а из скобок в которые заключены *f. 5 случае у нас указатель на ф-цию возвращающий указатель на char. В 6 случае у нас р1 указатель, а р2 нет, т.к. символ * всегда относиться к имени переменной а не к типу. Теперь вы можете удалять пробелы между * и типом или именем переменной/ф-ции( или добавлять их), это ничего не изменит(поймите это раз и на всегда!!! это не fortran).
Идем дальше - ссылки. Пример:
Код:
int x1 = 10;
int & x2 = x1;

int & x3 = x1, x4 = x2;

void foo( const QString& s);
Думаю тут все понятно по аналогии с указателями. В 3-м случае у нас х3 ссылка, а х4 - нет. При объявлении ф-ции параметр интерпритируеться как константная ссылка и только. Про пробелы аналогично с предыдущим абзацем.
Проще говоря использование * и &  с типами говорит нам об указателе и ссылке.
И так осталось разименование и взятие адреса. Взятие адреса используеться в rvalue выражениях и при инициализации:
Код:
int x1 = 10;
int * p = &x1;// р ссылаеться на х1
int * q;
q = &x1;// q ссылаеться на х1
Разименование используеться в lvalue, rvalue и при инициализации:
Код:
int x1 = 10, x2;
int * p = &x1;
x2 = * p; // исп. как rvalue
int x3 = *p;// x3 == 10
* p = x2 * x3;//исп. как lvalue
Возможно я что-то упустил или забыл(или в чем то ошибся знающим бейте по рукам но не сильно :)), поэтому вам следует прислушаться к советам окружающих и взяться за букварь по С++, потому как указатели и ссылки в С++ - это как таблица умножения в математике.
З.Ы. Думаю тему пора закрыть и так понятно чего человек не знает( на что ему не однократно указывали)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 23, 2008, 06:56
всем спасибо за весёлое утро! я плакал...
вот - http://dr--zoidberg.livejournal.com/291818.html - посмейтесь ещё ;)

den'ka, зачОт!
ветку сносить не буду - она и так в кандидатах ))


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: denka от Октября 23, 2008, 08:13
den'ka, зачОт!
ветку сносить не буду - она и так в кандидатах ))
Жаль стока писал, жене спать мешал, а тему удалят 8)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Вячеслав от Октября 23, 2008, 08:37
Так всем здрасте - меня тут очень долго не было , но Костя вытащил из сна - сказал что повеселиться можно ;)И точно ;)

Ну вот давайте посмотрим на прототип в QtAssistant

Код:
const char * qPrintable ( const QString & str )

Кутешники хитрые ребята, и написали так, что ясности нет, чему принадлежат * и &, ибо синтаксис позволяет.

И где здесь неоднозначность ? RTFM Страуса - в прототипе функции оператора взятия адреса объекта не может быть по опеделению .Слив зачитан.
Далее .. красота ассемблера - а уважаемй апологет ассемблера слышал такие ругательства ARM,MIPS,Cell ? Хотя суда по интеловскому синтаксису команд LEA BX скорее всего нет.... И даже для интела сейчас _нормальную_ прогу на ассемблере руками написать практически не реально - так-как просчитать конвеер для тогож SSE2 при нормальном взаимодействии с перефирией - не реально.... Да и никакая операционка нормальная не пустит на тот уровень где нужен щаз ассемблер...А нужен он IMHO при нестандартных железяках и программировании очень не тривиальных вещей....НУ нафига сейчас пытаться оптимизировать копейки , если 90% времени в обычной проге( я не беру случаев тяжелых расчетов - тама отдельная пестня) проц маятся дурью ? Особенно при наличии пары-четверки ядер ? И спрашиваеться зачем заниматься лишний писаниной ,когда ее(писанину) с чистой совестью можно свалить на компилятор ?
И еще - программу( не децкую поделку, а именно серьезную вещь) на ассемблере крома автора за приемлимое время человек со стороны просто не освоит.Каким бы он небыл спецом ... К сожалению это факт .. Особенно если прога делает нечто нетривиальное и во всю пользуеться особенностями конкретной архитектуры...Даже если она документирована по ГОСТ'у  и даже если автор согласен пообщаться ;)

Таки резюме - если в прикладной задаче сейчас вылезает асм - IMHO  в консерватории чего-то не впорядке ;)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 23, 2008, 08:47
н-да...последняя строка не в тему, но про понятность/читабельность кода на асме в принципе всё верно...

пофлеймим ишчо? )


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Вячеслав от Октября 23, 2008, 08:50
н-да...последняя строка не в тему, но про понятность/читабельность кода на асме в принципе всё верно...

пофлеймим ишчо? )
А почему не тему ? Пример _необходимости_ в _прикладной_ задаче асма в студию !!!


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 23, 2008, 08:57
мм...например, когда-то ещё в багланде писал приложение для манипуляции растровой графикой...как бы те же плюсы, скорость работы высокая (должна быть), но применение фильтров к большим картинкам тормозило безбожно - приходилось подобные операции писать на асме...
навскидку больше ничего не приходит на ум :)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: BRE от Октября 23, 2008, 09:35
мм...например, когда-то ещё в багланде писал приложение для манипуляции растровой графикой...как бы те же плюсы, скорость работы высокая (должна быть), но применение фильтров к большим картинкам тормозило безбожно - приходилось подобные операции писать на асме...
навскидку больше ничего не приходит на ум :)
В те далекие времена, очень часто использовался ассемблерный код, критические вещи можно было руками оптимизировать лучше, чем это делал компилятор. Сейчас я сильно сомневаюсь, что кто-то сможет за приемлемое время под современные процы написать код оптимальней чем это сделает комилятор.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 23, 2008, 13:45
Оо, взрыв мозга :)
Код:
QWidgetPrivate* const d_ptr;


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 23, 2008, 14:02
den'ka, зачОт!
ветку сносить не буду - она и так в кандидатах ))
Жаль стока писал, жене спать мешал, а тему удалят 8)

Ваш техт я себе в мемориз сохранил. Попросите одминов, может ветку в апстрим вернут.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 23, 2008, 14:14
Далее .. красота ассемблера - а уважаемй апологет ассемблера слышал такие ругательства ARM,MIPS,Cell ? Хотя суда по интеловскому синтаксису команд LEA BX скорее всего нет

Слышал-слышал, не беспокойтесь. Хотя писал код только для KP580BM80, Z80 и Intel x86 реального режима.


И спрашиваеться зачем заниматься лишний писаниной ,когда ее(писанину) с чистой совестью можно свалить на компилятор ?

Вы все правильно написали. Тема ассемблера была развернута только потому, что Константин не верил, что чел, работающий с  ассемблером не может осилить c/c++.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 23, 2008, 14:31
Тут вы меня пугаете... Как так неизвестно, сколько будет валиден возвращаемый указатель? То есть, если указатель защищен const, то известно? А если не защищен const, то неизвестно? Как то это странно все, проясните пажалусто.

Исправился. Это был ход хругой мысли (проконстантные ссылки на временные объекты) - Блог Герба Саттера (http://herbsutter.spaces.live.com/blog/cns!2D4327CC297151BB!378.entry). Почитайте, интересно. Кстате это вам ещё почва для размышления :)


Далее, по поводу const... const не дает менять объекты, которые не должны меняться по своей сути, таким образом оберегает от ошибок. Его нужно использовать везде, где только можно.

ЗЫ: Нужно читать нормальные книги, таких авторов как, например, Герб Саттер, а не пособия для чайников. И ненужно слушать, как было сказано выше, МЕГАПРОГЕРОВ ))).

ЗЫЫ: Низачто  неповерю, что у нормального вменяемого программиста на С\С++ возникнут проблемы с использованим, а темболее с пониманием пободных конструкций.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: pastor от Октября 23, 2008, 14:34
Код:
const char * qPrintable()
const char* qPrintable()
const char *qPrintable()

const QString & str
const QString& str
const QString &str

при компиляции даст одинаковый результат (хотя с & надо еще проверить..).

о_О

Эммм... я забираю свои слова насчет чтения книги Герба Саттера и прочих. Страус Трупа тоже врядли осилите... Читайте что-то её проще, и чем быстрее тем лучше, т.к. с пониманием С\С++ у вас дела обстоят весьма печально, и это факт!


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: bezzil от Октября 23, 2008, 16:14
спасиба за обширную тему подчерпнул для себя много нового.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: ритт от Октября 23, 2008, 18:52
поДчерпнул? ыыы))))
как дер?мо тазиком? )))))


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: SASA от Октября 23, 2008, 19:26
Прикольный топик, однако…
По поводу асма. Был когда-то написан код для работы с растровой графикой. И написан не просто из любви к искусству, а что б работало быстрее.
Прошло 10 лет. Код  переписали на си, и он стал работать быстрее! Но правда не на много. :)
Так что, поддерживаю Вячеслава.
Цитировать
Таки резюме - если в прикладной задаче сейчас вылезает асм - IMHO  в консерватории чего-то не впорядке.



Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 23, 2008, 19:52
Как-то выдохлись все, надо подбавить газку!

Код:
const char * qPrintable()
const char* qPrintable()
const char *qPrintable()

const QString & str
const QString& str
const QString &str

при компиляции даст одинаковый результат (хотя с & надо еще проверить..).

о_О

Эммм... я забираю свои слова насчет чтения книги Герба Саттера и прочих. Страус Трупа тоже врядли осилите... Читайте что-то её проще, и чем быстрее тем лучше, т.к. с пониманием С\С++ у вас дела обстоят весьма печально, и это факт!

Факт в том, что в случае с указателями я наизусть знаю, что компиляция будет одинаковой. В случае с сылками я догадываюсь, что тоже будет одинаково скомпилено, но до конца не уверен, о чем и сообщаю. Сейчас перепроверил - компилится одинаково.



Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Вячеслав от Октября 24, 2008, 18:29
Как-то выдохлись все, надо подбавить газку!

Код:
const char * qPrintable()
const char* qPrintable()
const char *qPrintable()

const QString & str
const QString& str
const QString &str

при компиляции даст одинаковый результат (хотя с & надо еще проверить..).

о_О

Эммм... я забираю свои слова насчет чтения книги Герба Саттера и прочих. Страус Трупа тоже врядли осилите... Читайте что-то её проще, и чем быстрее тем лучше, т.к. с пониманием С\С++ у вас дела обстоят весьма печально, и это факт!

Факт в том, что в случае с указателями я наизусть знаю, что компиляция будет одинаковой. В случае с сылками я догадываюсь, что тоже будет одинаково скомпилено, но до конца не уверен, о чем и сообщаю. Сейчас перепроверил - компилится одинаково.

Хм.... а собственно чем отличаються те два набора строк ? IMHO - ни чем ;)

const char* qPrintable()
char* qPrintable() const
разница есть ;)  А выше сказанное  одно и тож ;)

PS а когда начинается развлекуха с параметром функции типа указатель на Функу , у которой параметром свои указатели на другие функи(функи другого типа) и все это без typedef'ов ...... по неволе virtual'jd полюбишь ;)


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Tonal от Октября 26, 2008, 11:16
Да, весёлое чтово. :)

С точки зрения "передачи смысла" сейчас рулят Haskell, Python, Ruby, JS... а так же всякие DSL-и - ведь именно они используются для быстрого прототипирования.
PHP, 1C, AS - это где-то посередине. Это уже не DSL, но до полноценного современного языка им ещё ... :)

Так что ехели хочется именно "передачи смысла" то зачем использовать С++ - это один из самых сложных из манстримовских языков и предназначен он в первую очередь для создания высокоэффиктивных приложений.
Для этого его нужно довольно хорошо знать, тогда и понимание смысла конструкций не будет доставлять напряжения. :)

2 xintrea Кстати, вот, похоже именно твоя проблема описана:
Цитировать
Большинство людей, думающих, что они знают Си, на самом деле не понимают работы памяти или указателей. Это до них просто не доходит. Удивительно, как эти люди работают программистами, но ведь работают же!
...
Многие программисты на Си просто не знают, как заставить работать указатели. Я, как правило, не отказываюсь от кандидата из-за отсутствия у него какого-то навыка. Однако я обнаружил, что понимание указателей в Си — это не навык, а способность. В начале первого курса на факультете кибернетики набирается человек 200 вундеркиндов, писавших в четырехлетнем возрасте игрушки для Atari 800 на BASIC'е. Они хорошо проводят время, изучая Паскаль, но в один прекрасный день профессор заводит речь об указателях, и они внезапно перестают понимать. То есть абсолютно. 90% потока переходит на отделение политологии, обьясняя это тем, что на кибернетике мало симпатичных студенток. На самом же деле, по неизвестной причине часть человечества просто рождается без того отдела мозга, который понимает указатели. Указатели — это не навык, а способность, требующая особого мышления, и некоторые люди им просто не обладают.
Отсюда: http://russian.joelonsoftware.com/Articles/Interviewing.html

Так же полезно будет почитать:
http://russian.joelonsoftware.com/Articles/BacktoBasics.html
http://russian.joelonsoftware.com/Articles/AdviceforComputerScienceC.html
Да и вообще всё отсюда: http://russian.joelonsoftware.com/index.html


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: SASA от Октября 27, 2008, 17:44
Цитировать
Однако я обнаружил, что понимание указателей в Си — это не навык, а способность.
IMHO Бред.
Читаю С++ студентам. Что такое указатель не понимает только тот, кого я первый раз вижу на зачёте. Но это у них не от отсутствия способности.


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: xintrea от Октября 27, 2008, 22:33
С точки зрения "передачи смысла" сейчас рулят Haskell, Python, Ruby, JS... а так же всякие DSL-и - ведь именно они используются для быстрого прототипирования.
PHP, 1C, AS - это где-то посередине.

Ну я подумывал пользовать для разработки Python (с Qt биндингами), но что-то пока те программы, которые сделаны с использованием питона, мягко говоря работают кривовато. Часто вообще не работают. Дело видимо не в самом питоне как языке, а в библиотеках и версиях питона. В этом смысле в питоне сейчас имеем разброд и шатание. С Qt и C/C++ я хотябы уверен, что под виндой скомпиленый бинарь и нужные версии DLL, положенные рядом, обеспечат запуск и работу программы (хотя читал что нужно еще какое-то обновление системных dll, но для него есть готовый инсталлятор, и объяснить пользователю или сделать инсталлятор с обязательной установкой обновления не проблема). В линухе посложнее, но считается, что при установленной версии Qt не ниже требуемой, все должно работать.

А вот с питоном все очень плохо. Казалось бы - интерпретируемый язык, делай разработку, включай в релиз все нужные сторонние скрипты чтоб все гарантированно работало. Лицензия позволяет. Так нет же, ставишь прогу - она требует еще что-то, причем о требованиях узнаешь только тогда когда питоновский скрипт вывалится с ошибкой. Доставишь нужное - вроде начинает работать, но вываливается в другом месте. Начинаешь разбираться - там какая-то залипуха с версией питона, скрипту надо 2.5, а в системе другая. Обновишь версию - старые проги перестают работать.

Что далеко ходить - вон в последнем Inkscape 0.46 половина фильтров, сделанных на питоне, не работает. Я не настолько хорошо знаком с питоном, чтоб однозначно сказать - "при правильной подготовке релиза, Python программа будет везде работать так же, как и у разработчика". Пока то, что я наблюдаю - это то, что по каким-то непонятным причинам сделать нормальные, однозначно работающие проги, с использованием питона, не могут. Да, рассказы о том, что это мои кривые руки, не канают :). Программы должны делаться так, чтоб после установки они работали и все.


Так что ежели хочется именно "передачи смысла" то зачем использовать С++ - это один из самых сложных из майнстримовских языков, и предназначен он в первую очередь для создания высокоэффективных приложений?

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


> 2 xintrea Кстати, вот, похоже именно твоя проблема описана:

Большинство людей, думающих, что они знают Си, на самом деле не понимают работы памяти или указателей. Это до них просто не доходит. Удивительно, как эти люди работают программистами, но ведь работают же! ... Многие программисты на Си просто не знают, как заставить работать указатели.

Да, есть такое дело. Скажу больше, многие программисты, которые все-таки умеют работать с указателями на C/C++ (и думают, что они умеют работать с указателями), часто слабо понимают что на самом деле происходит в памяти, и как это выглядит.


Однако я обнаружил, что понимание указателей в Си — это не навык, а способность. ... На самом же деле, по неизвестной причине часть человечества просто рождается без того отдела мозга, который понимает указатели. Указатели — это не навык, а способность, требующая особого мышления, и некоторые люди им просто не обладают.

Вот это бред. Все зависит от преподавателя языка, или книг, в которых данный момент описан. Очень часто преподаватель сам не понимает о чем говорит, или специально объясняет так, чтобы его не поняли, специально усложняя традиционно "сложную" тему. Что касается книг, то у меня нет ни одной книги, в которой бы нормальным языком было написано про указатели. Один Подбельский чего стоит. Читаешь, разбираешься, и только еще больше вопросов возникает. Очень многие вещи просто не объясняются.

Например, нам объясняют, что переменная указателя - это адрес, который указывает на начало нужных данных. Значит, указатель на число int, и указатель на начало строки - это просто адреса. В 32x битных системах - это просто 4 байта смещения в сегменте данных. Коль указатель на int и указатель на начало строки имеют одно понятие "указатель", и имеют одинаковую структуру (4 байта в которых лежит адрес), значит указатели можно свободно присваивать. То есть по сути, можно легко положить в указатель на int адрес, который лежит в указателе на начало строки. Но тут же в книге мы видим, что нельзя присваивать указатели одного типа указателю другого типа. А почему нельзя то? А потому, пишут в книге, что указатели указывают на данные с разной структурой, и использование такой конструкции приведет к непредсказуемым последствиям. Пишут правильно.

Но не пишут почему нельзя-то такое провернуть? И на каком этапе будет ошибка? Люди начинают гадать - наверное, указатель - это какая-то структура, в которой помимо 4 байтов адреса еще и храниться инфа о типе объекта, на который указатель указывает. Иначе, простое присвоение одного указателя другому, было бы возможным. А профи знают, что это предположение неверное. Что указатель в C/C++ на 32 битной архитектуре - это действительно 4 байта с адресом, и ничего больше. А ошибка будет возникать просто на этапе компиляции, именно компилятор не даст присвоить указатель на один тип указателю на другой тип. А чтобы всетаки это сделать, надо пользоваться механизмами приведения типов, о чем в главах про указатели почему-то не пишут.

Хотя, одну книгу я видел, в которой вроде как было нормальное объяснение с точки зрения низкоуровеневого подхода ("низкоуровневый" я имею в виду низкосистемный уровень объяснения, а не объяснение "для тупых"). Книжка была страниц эдак на 1000 если не больше, на книжке фотография двух дяденек (авторов), а вот как называлась - не помню. Возможно, "Библия C/C++" или что-то в этом роде. Там вроде как было написано просто и понятно. Но стоила книга около 2300 руб, я такие деньги за книгу с серой газетной бумагой отдать не готов, какая бы полезная информация в ней не была написана. Кто-нить может по описанию сказать, что это за книга? Я б ее в электронном варианте посмотрел (хотя, конечно, читение с монитора не идет ни в какое сравнение с чтением с бумаги).


Название: Re: Как преобразовать указатель на QObject в указатель на объект нужного класса?
Отправлено: Tonal от Октября 29, 2008, 12:12
Используем Python в разработке уже более 5ти лет, в том числе и биндинг к Qt (всю гуйню на нём сейчас пишем).
Особой кривизны не наблюдали.
Выбрали связку Python + Qt именно из за высокой скорости разработки.
Лёгкость поддержки и сопровождения продуктов не отличается от C++ + Qt или Delphi.
С версиями разбираемся просто - py2exe - и у тебя набор из exe и dll-ек нужных для работы твоей проги. :)
В винде нельзя полагаться на то, что и куда у пользователя установлено в системе...

Ну а если ты распространяешь в исходниках - то нужно указывать и проверять минимальную и максимальную версию - благо делается это элементарно.
И тогда пользователь должен обеспечить нужную для работы версию.

А так, проблемы переносммости есть для любой системы/среды.
Про великолепную Java, у которой был слоган: "сделано однажды, работает везде" по этому поводу слоган чуть изменили: "сделоно однажды, отлаживаем везде!". :)