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 

Why it's a pointer not just a class

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





PostPosted: Thu Aug 24, 2006 7:24 am    Post subject: Why it's a pointer not just a class Reply with quote



Hi,

typedef std::vector<Vehicle*> VehicleList;

Vehicle is a UDT, or a class. Why is Vehicle* not just Vehicle in < >.
Which one is better and why? If you could explain it by laying out some
codes, it would be highly appreciated!

Thanks in advance,
Michael
Back to top
Daniel T.
Guest





PostPosted: Thu Aug 24, 2006 8:08 am    Post subject: Re: Why it's a pointer not just a class Reply with quote



"Michael" <michaelnx (AT) gmail (DOT) com> wrote:

Quote:
Hi,

typedef std::vector<Vehicle*> VehicleList;

Vehicle is a UDT, or a class. Why is Vehicle* not just Vehicle in < >.
Which one is better and why? If you could explain it by laying out some
codes, it would be highly appreciated!

class Vehicle { };
class Car : public Vehicle { };

vector<Vehicle> objVec;
objVec.push_back( Car() );
// bad, slices all Car behavior off of the object

vector<Vehicle*> ptrVec;
ptrVec.push_back( new Car() ); // good, all Car behavior is maintained

The problem with the second construct is that the vector doesn't know
when to delete the objects it contains. Some other object must track
that. This is often done with some sort of smart pointer.

vector< shared_ptr< Vehicle > > smartVec;
Back to top
Salt_Peter
Guest





PostPosted: Thu Aug 24, 2006 9:04 am    Post subject: Re: Why it's a pointer not just a class Reply with quote



Michael wrote:
Quote:
Hi,

typedef std::vector<Vehicle*> VehicleList;

Vehicle is a UDT, or a class. Why is Vehicle* not just Vehicle in < >.
Which one is better and why? If you could explain it by laying out some
codes, it would be highly appreciated!

Thanks in advance,
Michael

Because a Vehicle is abstract. Your goal here is to create a container
that holds derivatives of the Vehicle class. A Car is a type of
vehicle. A Truck is a type of Vehicle. A Bus is a type of Vehicle. Why
have to create a new container for each new type when a container of
Vehicles can store any type that is related to Vehicles, including a
mix of Vehicles?

Polymorphicly, you are creating a container of pointers to Vehicle
derivatives. That pointer to each element then allows the appropriate
behaviour to happen: brake(), reverse(), accelerate(). For example, a
car will not reverse() like a truck - a truck needs to sound a warning
buzzer first. The pointer essentially lets the vtable do its "magic".

As far as code is concerned:

#include <iostream>
#include <ostream>
#include <vector>

class Vehicle
{
public:
Vehicle() { }
virtual ~Vehicle() { } // virtual
virtual void reverse() = 0; // pure virtual -- see below
};

class Car : public Vehicle
{
public:
Car() { }
~Car() { std::cout << "~Car()" << std::endl; }
void reverse() { std::cout << "reversing" << std::endl; }
};

class Truck : public Vehicle
{
public:
Truck() { }
~Truck() { std::cout << "~Truck()" << std::endl; }
void reverse() { std::cout << "buzzer, reversing" << std::endl; }
};

int main()
{
std::vector< Vehicle* > vehicles;
// vehicles.push_back( new Vehicle ); error - Vehicle is abstract
vehicles.push_back( new Car );
vehicles.push_back( new Truck );

vehicles[ 0 ]->reverse();
vehicles[ 1 ]->reverse();

for ( int i = 0; i < vehicles.size(); ++i ) // or size_t
{
delete vehicles[ i ];
}
return 0;
}

/*
reversing
buzzer, reversing
~Car()
~Truck()
*/

The destructors are virtual too, they have to be for this to work. The
reason that reverse() was declared pure virtual in Vehicle is to force
the client programmer to provide a reverse() member function in order
to use this system.
Note that i can write a SportsCar class which derives from Car and
still use it in the vehicles container. A SportsCar is_a Car which is_a
Vehicle, hence a SportsCar is_a Vehicle.
If you don't yet see the benefits of such a system, consider
encapsulating the std::vector in a container class: all of a sudden,
you'ld have a container that can hold any Vehicle - including those
derivatives that have not been created yet (ie: SuperSportsCar or
TenTonTruck). Without having to modify the container in any way.
Thats a very powerful concept - your code becomes extensible without
having to modify the original classes.
Back to top
Heinz Ozwirk
Guest





PostPosted: Thu Aug 24, 2006 9:10 am    Post subject: Re: Why it's a pointer not just a class Reply with quote

"Michael" <michaelnx (AT) gmail (DOT) com> schrieb im Newsbeitrag
news:1156386253.269170.250710 (AT) i42g2000cwa (DOT) googlegroups.com...
Quote:
Hi,

typedef std::vector<Vehicle*> VehicleList;

Vehicle is a UDT, or a class. Why is Vehicle* not just Vehicle in < >.

Look how Vehicle is defined and how it is used.

Quote:
Which one is better and why?

Which one is better - a hammer or a tooth brush - and why?

None is better than the other. It depends on what you want to do.

Heinz
Back to top
Roland Pibinger
Guest





PostPosted: Tue Aug 29, 2006 9:10 am    Post subject: Re: Why it's a pointer not just a class Reply with quote

On Tue, 29 Aug 2006 00:58:37 +0200, "Bo Persson" <bop (AT) gmb (DOT) dk> wrote:
Quote:
You shouldn't store objects that are expensive to copy in a
standard container.

It's not mainly a question whether the container elements are
expensive to copy. The important distinction is between 'values' and
'objects' (objects in the OO sense). Objects are usually non-copyable
but may be accessed through multiple references (pointers in C++). STL
suppports only values. That causes the problems.

Best wishes,
Roland Pibinger
Back to top
I V
Guest





PostPosted: Wed Aug 30, 2006 9:10 am    Post subject: Re: Why it's a pointer not just a class Reply with quote

On Tue, 29 Aug 2006 03:30:08 -0700, Earl Purple wrote:
Quote:
and then there is, of course, boost:
[snip]


Not to mention boost::indirect_iterator,
http://boost.org/libs/iterator/doc/indirect_iterator.html

I'm not familiar with the Rogue Wave library, but a quick glance at the
documentation suggests that combining the standard containers with
boost::indirect_iterator accomplishes most, if not all, of what the RW
pointer containers do (from what I can tell, the RW classes don't deal
with ownership issues, which is probably the hardest part of a pointer
container to figure out).
Back to top
Roland Pibinger
Guest





PostPosted: Wed Aug 30, 2006 9:11 am    Post subject: Re: Why it's a pointer not just a class Reply with quote

On Tue, 29 Aug 2006 22:07:04 -0700, I V <wrongbad (AT) gmail (DOT) com> wrote:
Quote:
On Tue, 29 Aug 2006 03:30:08 -0700, Earl Purple wrote:
Not to mention boost::indirect_iterator,
http://boost.org/libs/iterator/doc/indirect_iterator.html

I'm not familiar with the Rogue Wave library, but a quick glance at the
documentation suggests that combining the standard containers with
boost::indirect_iterator accomplishes most, if not all, of what the RW
pointer containers do

Nope. When you use eg. std::sort with an boost::indirect_iterator it
swaps pointed-to objects not pointers. Containers, iterators and
algorithms need to become pointer aware for a real solution. Moreover,
the STL templates are notorious for their compiler error messages. An
iterator adapter adds another level of obfuscation to the program.

Quote:
(from what I can tell, the RW classes don't deal
with ownership issues, which is probably the hardest part of a pointer
container to figure out).

Why should a container for pointers be usable only for objects
allocated with new? Why is such a container supposed to delete
contained objects? A basic library container should not intermingle
container functionality and ownership. It should be usable for all
pointers (to heap-allocatd, to stack and to global objects). IMO, it's
a design flaw to write containers that insert pointers and require
that these pointers _must_ point to heap-allocated objects (which are
later deleted by the container). Of course, one can implement
ownership semantics on top of a basic pointer container but to build
ownership (and transfer of ownership to the container) into the
container is (put mildly) a highly questionable design decision.

Best wishes,
Roland Pibinger
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.