Add a non-implicit copy constructor to QEvent

Copying events is a bad idea but it is permitted, used at least in the
state machine framework and QApplication, which somehow found it
amusing to clone events. We can't forbid it because it would be
source-incompatible with Qt 4, and other ill-advised developer may be
doing this.

In the new copy functions and in the destructor, ensure that the d
pointer is null. We can't copy it if it isn't. The exception is for
DeferredDelete events, which use the d pointer to store the loop level
count. Such value must not be deleted.

In the future, if QEvent::d is used at the QEvent level, make sure to
adapt QCoreApplication::postEvent to store the counter somewhere else.

Task-number: QTBUG-25070
Change-Id: I1f2d3f3cfc891ec216df2e8b7dbe531524d21b26
Reviewed-by: Lars Knoll <lars.knoll@nokia.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
This commit is contained in:
Thiago Macieira 2012-04-04 14:25:12 -03:00 committed by Qt by Nokia
parent b25b3a9f8b
commit 2ec089bbc8
2 changed files with 43 additions and 0 deletions

View File

@ -283,6 +283,45 @@ QEvent::QEvent(Type type)
: d(0), t(type), posted(false), spont(false), m_accept(true)
{}
/*!
\internal
Attempts to copy the \a other event.
Copying events is a bad idea, yet some Qt 4 code does it (notably,
QApplication and the state machine).
*/
QEvent::QEvent(const QEvent &other)
: d(other.d), t(other.t), posted(other.posted), spont(other.spont),
m_accept(other.m_accept)
{
if (t != QEvent::DeferredDelete) {
// if QEventPrivate becomes available, make sure to implement a
// virtual QEventPrivate *clone() const; function so we can copy here
Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
}
}
/*!
\internal
Attempts to copy the \a other event.
Copying events is a bad idea, yet some Qt 4 code does it (notably,
QApplication and the state machine).
*/
QEvent &QEvent::operator=(const QEvent &other)
{
if (t != QEvent::DeferredDelete) {
// if QEventPrivate becomes available, make sure to implement a
// virtual QEventPrivate *clone() const; function so we can copy here
Q_ASSERT_X(!other.d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
}
t = other.t;
posted = other.posted;
spont = other.spont;
m_accept = other.m_accept;
return *this;
}
/*!
Destroys the event. If it was \link
QCoreApplication::postEvent() posted \endlink,
@ -293,6 +332,8 @@ QEvent::~QEvent()
{
if (posted && QCoreApplication::instance())
QCoreApplicationPrivate::removePostedEvent(this);
if (t != QEvent::DeferredDelete)
Q_ASSERT_X(!d, "QEvent", "Impossible, this can't happen: QEventPrivate isn't defined anywhere");
}

View File

@ -283,7 +283,9 @@ public:
};
explicit QEvent(Type type);
QEvent(const QEvent &other);
virtual ~QEvent();
QEvent &operator=(const QEvent &other);
inline Type type() const { return static_cast<Type>(t); }
inline bool spontaneous() const { return spont; }