PDA

View Full Version : Constructor call problem



MarkoSan
23rd May 2008, 14:17
Hi to all!

In my project I have following code chunk:
void CShoppingCartWidget::addEntry(structOrder& order)
{
// debug block
qDebug() << "order.iMerchandizeID=" << order.iMerchandizeID;
qDebug() << "order.iMerchandizeQuantity=" << order.iMerchandizeQuantity;
qDebug() << "order.rMerchandizePrice=" << order.rMerchandizePrice;
qDebug() << "order.rSubtotal=" << order.rSubtotal;
qDebug() << "order.strDisplayString=" << order.strDisplayString;
qDebug() << "order.strMerchandizeName=" << order.strMerchandizeName;
// **** END of debug block

QList<CMerchandizeOrder*> orders=shoppingCartModel()->orders();
//CMerchandizeOrder tempOrder(order);
CMerchandizeOrder* tempOrder=new CMerchandizeOrder(order);
Q_CHECK_PTR(tempOrder);As you can see, tempOrder an object of CMerchandizeOrder class that is created inside this code chunk. But, when I try to see with gdb which constructor is called and I set the breakpoints in first lines of all CMerchandizeOrder constructors, the app flow never comes to either breakpoint. The result of this is that the wrong order is added into table (default values instead of gathered from constructor parameter order). What is going on?! Please help! And the debug block shows right values.

MarkoSan
24th May 2008, 09:08
No one has idea what to do? I am really banging my head into a wall with this one ...

aamer4yu
24th May 2008, 09:41
Whats the prototype of CMerchandizeOrder constructors ??

Also you are using order and orders variable . My guess is you are passing the wrong one. Am not sure though. Can say more if u show what the CMerchandizeOrder ctor takes

ktk
24th May 2008, 11:52
Hi to all!

...
Q_CHECK_PTR(tempOrder);[/code]As you can see, tempOrder an object of CMerchandizeOrder class that is created inside this code chunk. But, when I try to see with gdb which constructor is called and I set the breakpoints in first lines of all CMerchandizeOrder constructors, the app flow never comes to either breakpoint. The result of this is that the wrong order is added into table (default values instead of gathered from constructor parameter order). What is going on?! Please help! And the debug block shows right values.

gcc/gdb has a general problem with breakpoint in constructors.
It (often) generates several copies of the constructor code
and fails to communicate the correct debug information.

A workaround for this kind of problem is to move the code of the
constructor body into some kind of init() member function and
call this function from the constructor.

MarkoSan
24th May 2008, 12:00
Well, here is this constructor:
class CMerchandizeOrder
{
public:
CMerchandizeOrder();
CMerchandizeOrder(structOrder& order);
....
}; and here is implemetantion:
CMerchandizeOrder::CMerchandizeOrder()
{
m_OrderValues.iMerchandizeID=0;
m_OrderValues.iMerchandizeQuantity=0;
m_OrderValues.rMerchandizePrice=0.00;
m_OrderValues.rSubtotal=0.00;
//m_OrderValues.strDisplayString=QString("Test Artikel Blank Constructor");
m_OrderValues.strMerchandizeName=QString("Test Artikel");
setDisplayString(m_OrderValues.iMerchandizeID,
m_OrderValues.strMerchandizeName,
m_OrderValues.iMerchandizeQuantity,
m_OrderValues.rMerchandizePrice,
m_OrderValues.rSubtotal);
}

CMerchandizeOrder::CMerchandizeOrder(structOrder& order)
{
m_OrderValues.iMerchandizeID=order.iMerchandizeID;
m_OrderValues.iMerchandizeQuantity=order.iMerchand izeQuantity;
m_OrderValues.rMerchandizePrice=order.rMerchandize Price;
m_OrderValues.rSubtotal=order.rSubtotal;
m_OrderValues.strMerchandizeName=order.strMerchand izeName;
setDisplayString(m_OrderValues.iMerchandizeID,
m_OrderValues.strMerchandizeName,
m_OrderValues.iMerchandizeQuantity,
m_OrderValues.rMerchandizePrice,
m_OrderValues.rSubtotal);
}

Will try with init function.

MarkoSan
24th May 2008, 13:08
I tried with init function and same result.

aamer4yu
24th May 2008, 19:00
ur code seems fine.... and am also begining to scratch my head :D
need to know 2 things -
1) is CShoppingCartWidget::addEntry reached ?? put qDebug for tempOrder as u did for order. What values you get there ? As for breakpoints in constructor, try qDebug in constructor. Sometimes breakpoints cannot be reached due to some other reason.

2) how are u adding the tempOrder to the table ? bec the code till now looks fine. may be u are making mistake somewhere else.

MarkoSan
24th May 2008, 19:29
Well, the addEntry() is reached and the model works fine since test data ARE added to table widget becuase I can see them. I've put qDebug() where you asked, the values are ok and here is the method that calls addEntry. I've doublechecked this tmpOrder and data are fetched ok:
void COperationWIndow::chooseMerchandize()
{
structOrder tmpOrder; // temp order
QString queryString("SELECT * from merchandize WHERE IdentificationNumber=%1 AND InUse=1;");
int iMerchandizeId=m_pMerchandizeBrowser->m_iSelected+1; // calcualtes id

queryString=queryString.arg(iMerchandizeId); // adds id to query string
qDebug() << "Query: " << queryString; // debug
QSqlQuery query(queryString); // sets up query from query string
qDebug() << query.lastError().text(); // debug
if (query.isActive())
{
while (query.next())
{
tmpOrder.iMerchandizeID=query.value(0).toInt();
tmpOrder.iMerchandizeQuantity=1;
tmpOrder.rMerchandizePrice=(qreal)query.value(3).t oDouble();
tmpOrder.rSubtotal=tmpOrder.iMerchandizeQuantity*t mpOrder.rMerchandizePrice;
tmpOrder.strMerchandizeName=QString(query.value(2) .toString());
tmpOrder.strDisplayString=QString::number(tmpOrder .iMerchandizeID)+strMerchandizeSpaceDelimiter+\
QString(tmpOrder.strMerchandizeName)+strMerchandiz eDelimiter+\
QString::number(tmpOrder.rMerchandizePrice, 'f', iMerchandizePricePrecision)+strMerchandizeSpaceDel imiter+\
QString::number(tmpOrder.iMerchandizeQuantity)+str MerchandizeSpaceDelimiter+\
QString::number(tmpOrder.rSubtotal, 'f', iMerchandizePricePrecision);
m_pShoppingCartWidget->addEntry(tmpOrder);
} // while
m_pShoppingCartWidget->resizeColumnsToContents();
m_pShoppingCartWidget->resizeRowsToContents();
if(m_pOrderButton->isEnabled()==false)
m_pOrderButton->setEnabled(true); // enables order buttn
} // if
}

I've been banging my head for a whole day now. :D

aamer4yu
25th May 2008, 07:50
What about the qDebug in constructors ?? are they OK too ??
if they are, then am sure u are overriding those values somewhere else

MarkoSan
25th May 2008, 09:59
What about the qDebug in constructors ?? are they OK too ??
if they are, then am sure u are overriding those values somewhere else

Thanks for useful hint. So, this is getting weirder and weirder :D. I've modified the both constructors in a way:
CMerchandizeOrder::CMerchandizeOrder()
{
resetOrder();
qDebug() << "Default constructor with parameter values:";
qDebug() << "m_OrderValues.iMerchandizeID=" << m_OrderValues.iMerchandizeID;
qDebug() << "m_OrderValues.iMerchandizeQuantity=" << m_OrderValues.iMerchandizeQuantity;
qDebug() << "m_OrderValues.rMerchandizePrice=" << m_OrderValues.rMerchandizePrice;
qDebug() << "m_OrderValues.rSubtotal=" << m_OrderValues.rSubtotal;
qDebug() << "m_OrderValues.strMerchandizeName=" << m_OrderValues.strMerchandizeName;
}

CMerchandizeOrder::CMerchandizeOrder(structOrder& order)
{
m_OrderValues.iMerchandizeID=order.iMerchandizeID;
m_OrderValues.iMerchandizeQuantity=order.iMerchand izeQuantity;
m_OrderValues.rMerchandizePrice=order.rMerchandize Price;
m_OrderValues.rSubtotal=order.rSubtotal;
m_OrderValues.strMerchandizeName=order.strMerchand izeName;
setDisplayString(m_OrderValues.iMerchandizeID,
m_OrderValues.strMerchandizeName,
m_OrderValues.iMerchandizeQuantity,
m_OrderValues.rMerchandizePrice,
m_OrderValues.rSubtotal);
qDebug() << "Constructor with parameter values:";
qDebug() << "m_OrderValues.iMerchandizeID=" << m_OrderValues.iMerchandizeID;
qDebug() << "m_OrderValues.iMerchandizeQuantity=" << m_OrderValues.iMerchandizeQuantity;
qDebug() << "m_OrderValues.rMerchandizePrice=" << m_OrderValues.rMerchandizePrice;
qDebug() << "m_OrderValues.rSubtotal=" << m_OrderValues.rSubtotal;
qDebug() << "m_OrderValues.strMerchandizeName=" << m_OrderValues.strMerchandizeName;
}

void CMerchandizeOrder::resetOrder()
{
m_OrderValues.iMerchandizeID=0;
m_OrderValues.iMerchandizeQuantity=0;
m_OrderValues.rMerchandizePrice=0.00;
m_OrderValues.rSubtotal=0.00;
//m_OrderValues.strDisplayString=QString("Test Artikel Blank Constructor");
m_OrderValues.strMerchandizeName=QString("Test Artikel");
setDisplayString(m_OrderValues.iMerchandizeID,
m_OrderValues.strMerchandizeName,
m_OrderValues.iMerchandizeQuantity,
m_OrderValues.rMerchandizePrice,
m_OrderValues.rSubtotal);
}. Then I've setup the breakpoint IMMEDIALTY AFTER addEntry() call and this is what I get from debug console:
warning: **** CONSTRUCTOR - WITH PARAMETERS values:

warning: m_OrderValues.iMerchandizeID= 15

warning: m_OrderValues.iMerchandizeQuantity= 1

warning: m_OrderValues.rMerchandizePrice= 5.43

warning: m_OrderValues.rSubtotal= 5.43

warning: m_OrderValues.strMerchandizeName= "McToast"

warning: **** DEFAULT CONSTRUCTOR - WITHOUT PARAMETERS values:

warning: m_OrderValues.iMerchandizeID= 0

warning: m_OrderValues.iMerchandizeQuantity= 0

warning: m_OrderValues.rMerchandizePrice= 0

warning: m_OrderValues.rSubtotal= 0

warning: m_OrderValues.strMerchandizeName= "Test Artikel"

warning: **** CONSTRUCTOR - WITH PARAMETERS values:

warning: m_OrderValues.iMerchandizeID= 0

warning: m_OrderValues.iMerchandizeQuantity= 0

warning: m_OrderValues.rMerchandizePrice= 0

warning: m_OrderValues.rSubtotal= 0

warning: m_OrderValues.strMerchandizeName= "Test Artikel"So, if addEntry is called ONE time, why is then first call of constructor (with parameters) ok and then there are other calls of constructor (both) which resets data to 0. WTF?!

aamer4yu
25th May 2008, 16:06
Few more things to look for -
1) what does QList<CMerchandizeOrder*> orders=shoppingCartModel()->orders(); do ??

2) in while(query.next()) , how many times is it executed ??

3) whats the full code in addEntry ??

my guess is thers prob in addEntry function only. Because thats where you were creating the CMerchandizeOrder objects.

add some debugging in addEntry. Before and after u create the CMerchandizeOrder object.

By the way,,, code is going into constructors :) isnt it

MarkoSan
25th May 2008, 16:23
Well, my answers:



QList<CMerchandizeOrder*> orders=shoppingCartModel()->orders(); gets full ist of previous orders in model, so I can check if processed order is already in list of orders so I can then update quantity (+1) and subtotal of order (recalculate quantity*price=subtotal)
query.next() is executesd excalty ONCE
here is addEntry code:
void CShoppingCartWidget::addEntry(structOrder& order)
{
// debug block
qDebug() << "order.iMerchandizeID=" << order.iMerchandizeID;
qDebug() << "order.iMerchandizeQuantity=" << order.iMerchandizeQuantity;
qDebug() << "order.rMerchandizePrice=" << order.rMerchandizePrice;
qDebug() << "order.rSubtotal=" << order.rSubtotal;
qDebug() << "order.strDisplayString=" << order.strDisplayString;
qDebug() << "order.strMerchandizeName=" << order.strMerchandizeName;
// **** END of debug block

QList<CMerchandizeOrder*> orders=shoppingCartModel()->orders();
CMerchandizeOrder* tempOrder=new CMerchandizeOrder(order);
Q_CHECK_PTR(tempOrder);

/*
tempOrder.iMerchandizeID=order.iMerchandizeID;
tempOrder.iMerchandizeQuantity=order.iMerchandizeQ uantity;
tempOrder.rMerchandizePrice=order.rMerchandizePric e;
tempOrder.rSubtotal=order.rSubtotal;
tempOrder.strDisplayString=order.strDisplayString;
tempOrder.strMerchandizeName=order.strMerchandizeN ame;
*/

if (!orders.contains(tempOrder))
{
// new merchandize
shoppingCartModel()->insertRows(0, 1, QModelIndex());
QModelIndex index=shoppingCartModel()->index(0, 0, QModelIndex());
shoppingCartModel()->setData(index,
//tempOrder.orderValues().strDisplayString,
tempOrder->orderValues().strDisplayString,
Qt::EditRole);
}
else
{
// merchandize exists, update quantity and subtotal
}
}

So, I was working on the base of qt 4.4.0 example and there the object is created in same fashion like in my module ...

aamer4yu
25th May 2008, 16:41
will have to go thru ur code all again [:D]

one thing i can suggest for the time being,,,
if ur code is going in constructor, are u able to pur breakpoint and see the call stack.
It will give u an idea wher the object is being created :)

MarkoSan
25th May 2008, 16:46
will have to go thru ur code all again [:D]

one thing i can suggest for the time being,,,
if ur code is going in constructor, are u able to pur breakpoint and see the call stack.
It will give u an idea wher the object is being created :)

I do not understand right now what do you mean, we already saw the object is being made in the wasy as it should THE FIRST TIME, but I cannot crack why are constructors (both) being called 4 times (as you saw from debug messages). I double checked and I confirm query.exec() is executed only ONCE.

aamer4yu
25th May 2008, 17:02
I mean,,, are u able to SET A BREAKPOINT in the constructor now ???

if yes,,, set the breakpoint... and see from the call stack from where the code was called

MarkoSan
25th May 2008, 17:26
The Eclipse IDE lets me set the breakpoint in constructor, but the breakpoint is never reached ...

aamer4yu
25th May 2008, 17:48
then how come you are able to get qDebug messages from the ctor :confused:

MarkoSan
25th May 2008, 17:58
then how come you are able to get qDebug messages from the ctor :confused:

I've setup breakpoint in the next line of code after constructor and then I copied messages from debug console. Messages stay in debug console after exiting from constructor ...

MarkoSan
26th May 2008, 08:46
If I setup breakpoint one line before CMerchandizeOrder constructor call and then try to step into CMerchandize constructor call I get something very weird, the dialog box shows which source file to choose to go into and there are several choices, which are all the same - qbytearray.h. I've enclosed a screenshot for better understanding. Is this maybe somekind of qt 4.4.0 bug?!

MarkoSan
26th May 2008, 16:42
Gurus like jacek, jpn, wysotta and other pleeeeeease help me!!!! :crying::crying::eek::confused:

MarkoSan
27th May 2008, 08:38
I've changed the code in addEntry() to:
void CShoppingCartWidget::addEntry(structOrder& order)
{
// debug block
qDebug() << "order.iMerchandizeID=" << order.iMerchandizeID;
qDebug() << "order.iMerchandizeQuantity=" << order.iMerchandizeQuantity;
qDebug() << "order.rMerchandizePrice=" << order.rMerchandizePrice;
qDebug() << "order.rSubtotal=" << order.rSubtotal;
qDebug() << "order.strDisplayString=" << order.strDisplayString;
qDebug() << "order.strMerchandizeName=" << order.strMerchandizeName;
// **** END of debug block

QList<CMerchandizeOrder*> orders=shoppingCartModel()->orders();
//CMerchandizeOrder* tempOrder=new CMerchandizeOrder(order);
//Q_CHECK_PTR(tempOrder);
CMerchandizeOrder tempOrder(order);

/*
tempOrder.iMerchandizeID=order.iMerchandizeID;
tempOrder.iMerchandizeQuantity=order.iMerchandizeQ uantity;
tempOrder.rMerchandizePrice=order.rMerchandizePric e;
tempOrder.rSubtotal=order.rSubtotal;
tempOrder.strDisplayString=order.strDisplayString;
tempOrder.strMerchandizeName=order.strMerchandizeN ame;
*/

if (!orders.contains(&tempOrder))
{
// new merchandize
shoppingCartModel()->insertRows(0, 1, QModelIndex());
QModelIndex index=shoppingCartModel()->index(0, 0, QModelIndex());
shoppingCartModel()->setData(index,
tempOrder.orderValues().strDisplayString,
//tempOrder->orderValues().strDisplayString,
Qt::EditRole);
}
else
{
// merchandize exists, update quantity and subtotal
}
} and I get same result. :crying:

MarkoSan
28th May 2008, 07:47
The problem has been solved, I've checked all sources related to table widget and I found some merchandize order field reset code from other developer that I did not have been aware god damn!!!! :o Stupid, stupid, stupid! Anyway, thanks all repliers for your time. But gdb still has problems with setting breakpoints in constructors ...

aamer4yu
28th May 2008, 14:04
relief for me too,,,, i was also begining to bang my head :D
i told ya,, u must be overriding somewher :p