QPointer-QWeakPointer-Qt5-Debacle
-
Hi all,
So I've recently noticed the whole QPointer vs QWeakPointer debacle that was caused in Qt5.
First they deprecate QPointer and let everybody switch to QWeakPointer in Qt4.6. Then they stuck out their tongue and removed the QObject-tracking capability in QWeakPointer in favor of... wait for it... QPointer! Yep, we should now use QPointer again, it was "un-deprecated". That slow, broken class from the old days – But of course, in Qt5 QPointer got a new backend, based on... have a guess...oh yes...QWeakPointer! (What kind of drugs are they taking and why can't we who have to deal with such decisions have some, too?)
Now, maybe you can tell me how we, who develop libraries, should handle this situation. I have clients that stick with Qt 4.x and some that want to switch to Qt5. Should I now maintain two separate branches, one for Qt5 and one for Qt4? Wasn't the switch supposed to be smooth?
If I change my code to now use QPointer again, people who compile with Qt5 will be fine. But people compiling with Qt 4.x will have the slow cripple that was QPointer in Qt 4, they should be using QWeakPointer. But when I stick with QWeakPointer my code won't compile with Qt5 because they removed functionality in QWeakPointer (the constructor taking QObject-subclasses). Should I now sprinkle
@
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
QWeakPointer<SomeClass> mPointer;
#else
QPointer<SomeClass> mPointer;
#endif...
#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
mPointer.data()->doSomething();
#else
mPointer->dpSomething();
#endif
@
all over the place? Was that the intent? Uglify all user's code?But then again, maybe I'm just completely mistaken and there is a way out of this debacle that I can't see at the moment. (They could've at least left the old QWeakPointer functionality, this way new projects who target Qt5-only can use the new QPointer while everybody else can continue using QWeakPointer.)
So, how did you manage to solve this issue in your code? Or if any trolls are listening: What the hell?!
-
Just because the constructor taking a QObject is deprecated doesn't mean the functionality isn't still there.
If QWeakPointer actually lost it's QObject-tracking capabilities, I would report that as a bug, and a critical one, too.
-
[quote author="Asperamanca" date="1367907884"]Just because the constructor taking a QObject is deprecated doesn't mean the functionality isn't still there.
[/quote]in qsharedpointer_impl.h, they've got all the QObject-targeted interface of QWeakPointer excluded from compilation via
@#if QT_DEPRECATED_SINCE(5, 0)
...
#endif@
I'd expect things that were marked as deprecated in a version not to be directly excluded in that version, but maybe in Qt6... However, that directive clearly excludes it for the default defines. I do wonder whether that's intended or a bug. I'd need to tell all my clients to include some hack like "#define QT_DISABLE_DEPRECATED_BEFORE QT_VERSION_CHECK(0, 0, 0)" before including any Qt headers in their projects and probably even recompile Qt with that flag on some systems. Can't be serious. -
I don't have a working Qt5 environment. Could you check it with a small example? If they've really broken that, I could submit this as a bug via Qt commercial support. While we currently stick to Qt4, there's always the future to think of.
-
Checked it, they really excluded the newly deprecated interface by default.
@#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QWeakPointer>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();QWeakPointer<QWidget> mPointer;
private:
Ui::MainWindow *ui;
};#endif // MAINWINDOW_H@
@#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
mPointer(this),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}MainWindow::~MainWindow()
{
delete ui;
}@Works with Qt4.x, fails with Qt5.0.x saying
@mainwindow.cpp: In constructor 'MainWindow::MainWindow(QWidget*)':
mainwindow.cpp:7:24: error: no matching function for call to 'QWeakPointer<QWidget>::QWeakPointer(MainWindow* const)'
mainwindow.cpp:7:24: note: candidates are: [blablabla]@as expected when such a constructor isn't defined.
-
I have compared the source codes 4.8.4. against 5.0.2, and sure enough, they've just defined it away. I have submitted a support request, and expect an official statement how application and library developers are expected to handle such back-and-forth tactics.
-
Hi Asperamanca, can you please post a link to your support request here? So that others can follow it.
Anyway, there is a large backlog in the JIRA issue tracker, so the request might get buried under lots of other requests. If you don't get any response in a week, try posting the question to the Interest mailing list, which is a lot more active: http://lists.qt-project.org/mailman/listinfo/interest
-
Actually, I found an official statement: http://www.macieira.org/blog/2012/07/continue-using-qpointer/
-
Thanks for the link. It still doesn't explain why no way was implemented that would allow someone to specifically allow the QWeakPointer - QObject use case.
I don't know how to post a link to my support request - I can only access it via my Qt commercial user account. But I'll keep you posted about what's going on.
-
Ah, I didn't realize you submitted a commercial support request. Yes, please keep us updated.
I'm not familiar with the intricacies of the different smart pointer classes, but I was under the impression that "deprecated" means "not recommended but still available", not "removed from the library". It could be an error.
-
Yes, the flip-flopping over QWeakPointer is annoying to those who immediately adjusted all their code. It seems though that QPointer works in Qt4 programs although for a couple of dot releases it may generate a deprecation warning at compile time (not in 4.8), and it works in Qt 5.0. The solution would seem to be use QPointer and ignore the late unpleasantness. No version dependent #ifdef required.
I may be wrong, but this should only be a problem to clients of your library if the QWeakPointer is part of the API, which you have just changed only to change back, or the library has not been programmed to maintain binary compatibility (so changing private members could break things).
-
The support answer suggests to use
@DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0@
-
Thanks, Asperamanca. Not an ideal solution, but it does let code run.