[Qt-interest] Qt object initialisation list problem

K. Frank kfrank29.c at gmail.com
Fri Nov 19 17:06:24 CET 2010


Hi John and Andy -

I don't understand what's going wrong here or how to fix it, but
I think that the comment about creating the QPointF's on the heap
is a red herring.

On Fri, Nov 19, 2010 at 7:31 AM, John McClurkin <jwm at nei.nih.gov> wrote:
> Andy Bolsover wrote:
>> I have a small test program to draw a Bezier curve with 2 end points and
>> ...
>>
>>             Bezier *bez = new Bezier(QPointF(0,100), QPointF(0,0),
>> QPointF(100,0), QPointF(100,100));
>> ...
>
> My guess would be that you are constructing new QPointF objects in the
> call to Bezier. Try constructing the QPointF first, then passing them in.
>        QPointF *a = new QPointF(0,100);
>        QPointF *b = new QPointF(0,0);
>        QPointF *c = new QPointF(100,0);
>        QPointF *d = new QPointF(100,100);
>
>        Bezier *bez = new Bezier(*a, *b, *c, *d);

I don't see how this can matter (unless there is some c++ nuance
I'm missing).

>From below, the Bezier constructor is call by value, so it should
neither know nor care whether the QPointF's passed in are local
temporary variables on the stack, or dereferenced values of pointers
pointing to QPoiutF's on the heap.  (In the latter case, you
presumably have a small memory leak, unless you delete the
QPointF's in some other piece of code.)

In either case, QPointF's should be copy-constructed into the
private QPointF member variables when the constructor is called
(and the local temporary variables are still valid at this point in time).

> ...
>>
>> The Bezier constructor receives four QPointF which are stored in private
>> variables.
>> ...

>> These QPointF are also used to initialise the locations of the four
>> Controller objects
>>
>> If I use the passed-in QPointF directly to set positions of the
>> Controller objects everything is ok,
>>
>> But if I use the private variables to set positions of the Controller
>> objects the initial locations are wrong and the private variables are
>> also altered.

This seems odd.  The setPos() member function of your Controller
takes its QPointF's as const references, so it shouldn't be able
to change them.

>> As a result the Bezier curve is the wrong shape when first drawn
>>
>> I have been looking at this for long enough without seeing what is going
>> wrong.
>>
>> I thought it was a C++ problem at first – not Qt, but the problem goes
>> away when I simplify the test program by removing the Qt
>>
>> Any suggestions on what I have done wrong?

Unfortunately not.

>>
>> Here is the code for the Bezier and its Controller objects.
>>
>> class Controller : public QGraphicsEllipseItem {
>> ...
>>
>> class Bezier : public QGraphicsItem {
>>
>> public:
>>
>>             Bezier(QPointF pA, QPointF pB, QPointF cA, QPointF cB,
>> QGraphicsItem *parent = 0, QGraphicsScene *scene = 0);

Bezier gets its QPointF's by value.

>> ...
>>
>> Bezier::Bezier(QPointF pA, QPointF pB, QPointF cA, QPointF cB,
>> QGraphicsItem *parent, QGraphicsScene *scene)
>>
>>                         : QGraphicsItem(parent, scene), m_pA(pA),
>> m_pB(pB), m_cA(cA), m_cB(cB) {

The QPointF's are copy-constructed into the member variables.

>> ...
>> //          The following initialisation method does not work
>>
>> //          m_pA, m_pB, m_cA, and m_cB are all initialised wrongly (0,0)

Just to check, are m_pA, et al., initialized wrongly, i.e., at the time of
their initialization in the Bezier's constructor's initializer list?

Or do they start out with the correct values, but then end up with bad
values, after calling setPos(m_pA) etc.?

>>
>> //          endA position is initialised correctly, but the other
>> Controllers are wrongly located at 0, 0
>>
>> /*          endA->setPos(m_pA);
>>             endB->setPos(m_pB);
>>             controlA->setPos(m_cA);
>>             controlB->setPos(m_cB);
>> */

setPos takes a const ref:  setPos ( const QPointF & )

So it shouldn't be changing the value of m_pA, etc.

>>
>> //          The following initialisation method works OK
>>
>> //          m_pA, m_pB, m_cA, and m_cB are all initialised ok
>>
>> //          endA, endB, controlA & controlB are all positioned OK
>>
>>             endA->setPos(pA);
>>             endB->setPos(pB);
>>             controlA->setPos(cA);
>>             controlB->setPos(cB);
>> }

This is quite odd.  I don't see anything wrong with what you are doing.

The only thing I can think of at this point would be to poke around
with the debugger and try to find out where the m_pA, et al. are
getting set to the bad values (0, 0).

Or, if you can whittle it down to a minimal, self-contained example
program that displays the bug, I (we?) might be able to take a look
at it.

>> ...

Good luck.


K. Frank




More information about the Qt-interest-old mailing list