C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Semi-newbie question concerning programming style

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Alf P. Steinbach
Guest





PostPosted: Thu Jan 29, 2004 6:57 pm    Post subject: Re: Semi-newbie question concerning programming style Reply with quote



On Thu, 29 Jan 2004 19:42:59 -0800, Peter Forthmann <peter (AT) peterundsinje (DOT) de> wrote:

Quote:
I'm relatively new to C++ programming and have a few questions:

Having worked with QT for some time, I like instantiating my objects with the new operator and
juggling with pointers to them rather than using the objects directly.

As my programs become more and more complex I am at a point where it might be wise to ask the
experts about some issues. Please look at the two following examples:

I have a main class DProjectionDataSet and a derived class PDSet inherited from DProjectionDataSet.

Let the Copy() function be a member of DProjectionDataSet:



DProjectionDataSet *DProjectionDataSet::Copy ()
{
DProjectionDataSet *new_data_set = new DProjectionDataSet ();
...
copy 'this' to 'new_data_set'
...
return new_data_set;
}


The following then works in main:

PDSet *dataset = new PDSet (input_file, MEM);
PDSet *slice = (PDSet*)dataset->Copy ();

, but I have to have the cast in the second line (lest I get: error: invalid conversion from
`DProjectionDataSet*' to `PDSet*'). I thought that due to the inheritance dataset->Copy() would
return a PDSet, but according to my Linux g++ compiler it returns a DProjectionDataSet, which I have
to cast to a PDSet.

The dynamic (runtime) type is PDSet*, the static (compile-time) type is
DProcejectionDataSet*.

But that's only because you haven't used C++'s allowance for covariant
return types.

With a conforming compiler you can declare PDSet::Copy as


PDSet* Copy() const { ... }


and it will still override DProjectionDataSet::Copy.


Quote:
I have also defined an operator+:



DProjectionDataSet *DProjectionDataSet::operator+ (DProjectionDataSet *data_set)
{
DProjectionDataSet *sum = this->Copy ();
...
add the contents of 'data_set' to 'sum'
...
return sum;
}

Unconventional return type.

To make operator+ work as expected it should return "DProjectDataSet const&".

For efficiency you might consider also providing operator+=.




Quote:
1.) Could it be that by the way I instantiate my classes in main (i.e. via pointers) I make it
difficult/impossible for the compiler to recognize how the objects are derived from each other and
how the data types correspond?

No, the difficulties stem from not using covariant return type.



Quote:
2.) Is the pointer-oriented approach a bad philosophy (the QT people do it quite a lot)? I kind of
like how you can pass the pointers around. I tried rewriting the code using references, but it got
really awkward. Maybe I was doing it wrong.

Using raw pointers is not a good idea.

Consider at least using std::auto_ptr (also see e.g. boost::shared_ptr).




Quote:
3.) If it is ok to stick to 2.) are there more elegant possibilities as the ones shown above, i.e.
can I get rid of the casting?

Yes, you can; see above.


Back to top
Rolf Magnus
Guest





PostPosted: Thu Jan 29, 2004 11:20 pm    Post subject: Re: Semi-newbie question concerning programming style Reply with quote



Alf P. Steinbach wrote:

Quote:
2.) Is the pointer-oriented approach a bad philosophy (the QT people
do it quite a lot)? I kind of like how you can pass the pointers
around. I tried rewriting the code using references, but it got really
awkward. Maybe I was doing it wrong.

Using raw pointers is not a good idea.

Consider at least using std::auto_ptr (also see e.g.
boost::shared_ptr).

Well, that wouldn't be such a good idea. Qt uses its own mechanism to
delete the objects. There are two types of objects. One uses a simple
value-based approach that most often internally uses COW (like strings
and pixmaps e.g.), the other type is derived from QObject, and each
object of that type has a parent object (think of all the buttons and
stuff in a dialog having that dialog as parent e.g.), and when the
parent is destroyed, all the children are automatically destroyed too.
Shared pointers don't really fit in there, and aren't actually needed.

Quote:
3.) If it is ok to stick to 2.) are there more elegant possibilities
as the ones shown above, i.e. can I get rid of the casting?

Yes, you can; see above.

Btw: never use C style casts. Instead use the new C++ casts, _if_ you
need to cast at all.


Back to top
Alf P. Steinbach
Guest





PostPosted: Thu Jan 29, 2004 11:45 pm    Post subject: Re: Semi-newbie question concerning programming style Reply with quote



On Fri, 30 Jan 2004 00:20:41 +0100, Rolf Magnus <ramagnus (AT) t-online (DOT) de> wrote:

Quote:
Alf P. Steinbach wrote:

2.) Is the pointer-oriented approach a bad philosophy (the QT people
do it quite a lot)? I kind of like how you can pass the pointers
around. I tried rewriting the code using references, but it got really
awkward. Maybe I was doing it wrong.

Using raw pointers is not a good idea.

Consider at least using std::auto_ptr (also see e.g.
boost::shared_ptr).

Well, that wouldn't be such a good idea. Qt uses its own mechanism to
delete the objects. There are two types of objects. One uses a simple
value-based approach that most often internally uses COW (like strings
and pixmaps e.g.), the other type is derived from QObject, and each
object of that type has a parent object (think of all the buttons and
stuff in a dialog having that dialog as parent e.g.), and when the
parent is destroyed, all the children are automatically destroyed too.
Shared pointers don't really fit in there, and aren't actually needed.

I agree that it it's a bad idea to impose more than one ownership regime.

If you can never create an object that isn't owned by another object, then
a boost::shared_ptr (say) would be an additional ownership, which could
have disastrous results. But perhaps Qt offers some smart-pointer
classes itself, smart-pointer classes that cooperate with the hierarchical
ownership?

On the other hand, if free-standing objects can be created, then any
smart-pointer would probably be an improvement over raw pointers, for this
case.




Quote:
3.) If it is ok to stick to 2.) are there more elegant possibilities
as the ones shown above, i.e. can I get rid of the casting?

Yes, you can; see above.

Btw: never use C style casts. Instead use the new C++ casts, _if_ you
need to cast at all.

Yup. I forgot to mention that.


Back to top
Peter Forthmann
Guest





PostPosted: Fri Jan 30, 2004 3:42 am    Post subject: Semi-newbie question concerning programming style Reply with quote

Hi,

I'm relatively new to C++ programming and have a few questions:

Having worked with QT for some time, I like instantiating my objects with the new operator and
juggling with pointers to them rather than using the objects directly.

As my programs become more and more complex I am at a point where it might be wise to ask the
experts about some issues. Please look at the two following examples:

I have a main class DProjectionDataSet and a derived class PDSet inherited from DProjectionDataSet.

Let the Copy() function be a member of DProjectionDataSet:



DProjectionDataSet *DProjectionDataSet::Copy ()
{
DProjectionDataSet *new_data_set = new DProjectionDataSet ();
...
<copy 'this' to 'new_data_set'>
...
return new_data_set;
}


The following then works in main:

PDSet *dataset = new PDSet (input_file, MEM);
PDSet *slice = (PDSet*)dataset->Copy ();

, but I have to have the cast in the second line (lest I get: error: invalid conversion from
`DProjectionDataSet*' to `PDSet*'). I thought that due to the inheritance dataset->Copy() would
return a PDSet, but according to my Linux g++ compiler it returns a DProjectionDataSet, which I have
to cast to a PDSet.



I have also defined an operator+:



DProjectionDataSet *DProjectionDataSet::operator+ (DProjectionDataSet *data_set)
{
DProjectionDataSet *sum = this->Copy ();
...
<add the contents of 'data_set' to 'sum'>
...
return sum;
}



Also then the add operation works ok in main, but it's even worse than in the previous example,
because I need to dereference the first operator also:

PDSet *sum = (PDSet*)(*slice + slice);




My questions now are the following:

1.) Could it be that by the way I instantiate my classes in main (i.e. via pointers) I make it
difficult/impossible for the compiler to recognize how the objects are derived from each other and
how the data types correspond?

2.) Is the pointer-oriented approach a bad philosophy (the QT people do it quite a lot)? I kind of
like how you can pass the pointers around. I tried rewriting the code using references, but it got
really awkward. Maybe I was doing it wrong.

3.) If it is ok to stick to 2.) are there more elegant possibilities as the ones shown above, i.e.
can I get rid of the casting?


Thanks a lot for your help guys,

Peter.
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.