tags:

views:

304

answers:

2

Hi Folks,

Learning C++, so be gentle :)...

I have been designing my application primarily using heap variables (coming from C), so I've designed structures like this:

QList<Criteria*> _Criteria;
// ...
Criteria *c = new Criteria(....);
_Criteria.append(c);

All through my program, I'm passing pointers to specific Criteria, or often the list. So, I have a function declared like this:

QList<Criteria*> Decision::addCriteria(int row,QString cname,QString ctype);
Criteria * Decision::getCriteria(int row,int col)

which inserts a Criteria into a list, and returns the list so my GUI can display it.

I'm wondering if I should have used references, somehow. Since I'm always wanting that exact Criteria back, should I have done:

QList<Criteria> _Criteria;
// ....
Criteria c(....);
_Criteria.append(c);

...

QList<Criteria>& Decision::addCriteria(int row,QString cname,QString ctype);
Criteria& Decision::getCriteria(int row,int col)

(not sure if the latter line is syntactically correct yet, but you get the drift).

All these items are specific, quasi-global items that are the core of my program.

So, the question is this: I can certainly allocate/free all my memory w/o an issue in the method I'm using now, but is there are more C++ way? Would references have been a better choice (it's not too late to change on my side).

TIA

Mike

+1  A: 

I would return QList<Criteria> as a plain value. QList is one of Qt's shared classes, meaning that its internal representation is shared between multiple instances so long as none of them are modified.

If the Criteria class is fairly complex, such that an incidental copy made because one of the lists is modified at some point incurs noticable overhead, then I would use QSharedData in the implementation of Criteria so that it, too, is only copied as needed.

This approach has two downsides: one, the copying, if any, is implicit and may happen when you don't expect it to, and two, it doesn't allow for polymorphic use of Criteria. If you have Criteria as the root of a class hierarchy, then you must use pointers. In that case, I would use shared_ptr from Boost or C++ TR1 to avoid memory management hassles, or make Critera inherit publicly from QObject and make all Critera objects children of Decision.

Michael E
+1  A: 

I don't think references would be a better choice. If you are dynamically allocating these objects, you still need keep a copy of the pointer around to delete later. Plus, when passing around pointers you don't have to worry about copy constructors or an implicit sharing technique like QSharedData. You'll still get "that exact Criteria back".

My advice is: Unless you have a really good reason to make things more complex, keep it simple.

However, from a Qt standpoint you should generally not pass around pointers or references to Qt objects. These objects do use implicit sharing so they don't act like "normal" C++ objects. If you are still learning C++ I'd suggest leaving this technique out of your own code for now. But to use Qt effectively you need to understand how it works so I recommend reading more about it here:

http://qt.nokia.com/doc/4.6/implicit-sharing.html

Good luck!

EDIT:

One thing I forgot to mention. If you know you don't want you class to be copied, you can enforce this by declaring a private copy constructor and operator= overload:

class A
{
    //Code goes here
private:
    A(const A&);
    A& operator=(const A&);
};
Scott Danahy