473,404 Members | 2,195 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,404 software developers and data experts.

Why it's a pointer not just a class

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

Aug 24 '06 #1
19 1622
"Michael" <mi*******@gmail.comwrote:
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<VehicleobjVec;
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;
Aug 24 '06 #2

Michael wrote:
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.

Aug 24 '06 #3
"Michael" <mi*******@gmail.comschrieb im Newsbeitrag
news:11**********************@i42g2000cwa.googlegr oups.com...
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.
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

Aug 24 '06 #4
On 23 Aug 2006 19:24:13 -0700, "Michael" <mi*******@gmail.comwrote:
>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!
Good question. The answer simply is that the creator of STL hates OO
programming. He designed STL for values (ints, doubles, small structs,
....) only. BTW, if you want it you can have it, a STL-container for
(non-copyable) polymorphic objects:
http://www.codeproject.com/vcpp/stl/ptr_vecto.asp

Best wishes,
Roland Pibinger
Aug 24 '06 #5

"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:44**************@news.utanet.at...
On 23 Aug 2006 19:24:13 -0700, "Michael" <mi*******@gmail.comwrote:
>>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!

Good question. The answer simply is that the creator of STL hates OO
programming. He designed STL for values (ints, doubles, small structs,
...) only. BTW, if you want it you can have it, a STL-container for
(non-copyable) polymorphic objects:
http://www.codeproject.com/vcpp/stl/ptr_vecto.asp
What does the "creator of STL" have to do with anything?

It's simply a question on the usage of it, and when/why one would prefer to
use pointers instead of objects in a vector.

And the answer, as has been pointed out elsethread, is that using pointers
allows one to take advantage of polymorphism, by storing pointers to base
class objects while actually instanciating a variety of derived-class
instances.

-Howard


Aug 24 '06 #6
Howard wrote:
"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:44**************@news.utanet.at...
>On 23 Aug 2006 19:24:13 -0700, "Michael" <mi*******@gmail.comwrote:
>>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!
Good question. The answer simply is that the creator of STL hates OO
programming. He designed STL for values (ints, doubles, small structs,
...) only. BTW, if you want it you can have it, a STL-container for
(non-copyable) polymorphic objects:
http://www.codeproject.com/vcpp/stl/ptr_vecto.asp

What does the "creator of STL" have to do with anything?

It's simply a question on the usage of it, and when/why one would prefer to
use pointers instead of objects in a vector.

And the answer, as has been pointed out elsethread, is that using pointers
allows one to take advantage of polymorphism, by storing pointers to base
class objects while actually instanciating a variety of derived-class
instances.
Roland has made his distaste for pointers in Standard containers very
evident in his other posts.
Aug 24 '06 #7
On Thu, 24 Aug 2006 15:36:52 GMT, "Howard" <al*****@hotmail.com>
wrote:
>It's simply a question on the usage of it, and when/why one would prefer to
use pointers instead of objects in a vector.
And the answer, as has been pointed out elsethread, is that using pointers
allows one to take advantage of polymorphism, by storing pointers to base
class objects while actually instanciating a variety of derived-class
instances.
Please take a look at other container libraries apart from STL (Rogue
Wave, MFC, Qt3 ...). They have containers for pointers and containers
for values. It's just STL that's 'value only'. Rouge Wave e.g. has a
RWTPtrDlist for pointers and a RWTValDlist vor values. The OP's
questions is valid.

Best regards,
Roland Pibinger
Aug 24 '06 #8
On Thu, 24 Aug 2006 16:25:21 GMT, red floyd <no*****@here.dudewrote:
>
Roland has made his distaste for pointers in Standard containers very
evident in his other posts.
Of course, that's not a matter of taste or distaste. If you want to
understand STL you simply need to understand the consequences of value
semantics.

Best wishes,
Roland Pibinger
Aug 24 '06 #9

"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:44*************@news.utanet.at...
On Thu, 24 Aug 2006 15:36:52 GMT, "Howard" <al*****@hotmail.com>
wrote:
>>It's simply a question on the usage of it, and when/why one would prefer
to
use pointers instead of objects in a vector.
And the answer, as has been pointed out elsethread, is that using pointers
allows one to take advantage of polymorphism, by storing pointers to base
class objects while actually instanciating a variety of derived-class
instances.

Please take a look at other container libraries apart from STL (Rogue
Wave, MFC, Qt3 ...). They have containers for pointers and containers
for values. It's just STL that's 'value only'. Rouge Wave e.g. has a
RWTPtrDlist for pointers and a RWTValDlist vor values. The OP's
questions is valid.
I haven't said that the OP's questions are not valid. I'm suggesting that
you're not addressing his questions, because you're misunderstanding what
was asked.

He asked why some particular code which used a vector was written the way it
was. Also, he asked when and why one would want to use pointers in a
vector, as in the example. And that was answered, by me and by others.

Your response implied he was asking something about why vector the vector
class itself is written the way it is.

I could be wrong on what he or you meant, but that's how I (and apparently
the others) interpreted his questions (and your response).

-Howard

Aug 24 '06 #10
On Thu, 24 Aug 2006 20:55:46 GMT, "Howard" <al*****@hotmail.com>
wrote:
>I haven't said that the OP's questions are not valid. I'm suggesting that
you're not addressing his questions, because you're misunderstanding what
was asked.
He asked why some particular code which used a vector was written the way it
was. Also, he asked when and why one would want to use pointers in a
vector, as in the example. And that was answered, by me and by others.
Your response implied he was asking something about why vector the vector
class itself is written the way it is.
I could be wrong on what he or you meant, but that's how I (and apparently
the others) interpreted his questions (and your response).
Maybe I've iterpreted too much into the question. IMO, it's worth to
point out that there exist C++ libraries other than STL where a
container of pointes to Vehicles would be written as e.g.:

int main(){
RWTPtrDlist<Vehiclevehicles;
//...
}
see:
http://www.roguewave.com/support/doc...tptrdlist.html
Best regards,
Roland Pibinger
Aug 24 '06 #11
Roland Pibinger wrote:
On Thu, 24 Aug 2006 16:25:21 GMT, red floyd <no*****@here.dudewrote:
>>
Roland has made his distaste for pointers in Standard containers very
evident in his other posts.

Of course, that's not a matter of taste or distaste. If you want to
understand STL you simply need to understand the consequences of value
semantics.
Well, that goes for the language as a whole. Class type variables in C++
have value semantics with all its (surprising) consequences like slicing.
The design decision for the containers in STL is firmly rooted in the
fundamental feature of C++ to have value semantics and fake/model reference
semantics through pointers. I do not think that this trait of C++ needs to
be understood for STL containers separately.
Best

Kai-Uwe Bux
Aug 24 '06 #12
Roland Pibinger wrote:
Maybe I've iterpreted too much into the question. IMO, it's worth to
point out that there exist C++ libraries other than STL where a
container of pointes to Vehicles would be written as e.g.:

int main(){
RWTPtrDlist<Vehiclevehicles;
//...
}
There are also libraries with threads, windows, directories, symbolic
algebra... I don't see the need to point the things the standard library
does not have. It's shorter the other way.

--
Salu2
Aug 24 '06 #13


red floyd wrote:
Howard wrote:
>"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:44**************@news.utanet.at...
>>On 23 Aug 2006 19:24:13 -0700, "Michael" <mi*******@gmail.comwrote:

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!
<snip>
>It's simply a question on the usage of it, and when/why one would
prefer to use pointers instead of objects in a vector.

And the answer, as has been pointed out elsethread, is that using
pointers allows one to take advantage of polymorphism, by storing
pointers to base class objects while actually instanciating a variety
of derived-class instances.
I believe another important things is that storing pointers would not
result in default constructors being called or required. Also, using a
pointer would not call a copy constructor when placing the object into
the container.

--
Angelo Fraietta
http://www.smartcontroller.com.au/~angelo/

Aug 28 '06 #14

"Angelo Fraietta" <an******@bigpond.comskrev i meddelandet
news:12*************@corp.supernews.com...
>

red floyd wrote:
>Howard wrote:
>>"Roland Pibinger" <rp*****@yahoo.comwrote in message
news:44**************@news.utanet.at...

On 23 Aug 2006 19:24:13 -0700, "Michael" <mi*******@gmail.com>
wrote:

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!

<snip>
>>It's simply a question on the usage of it, and when/why one would
prefer to use pointers instead of objects in a vector.

And the answer, as has been pointed out elsethread, is that using
pointers allows one to take advantage of polymorphism, by storing
pointers to base class objects while actually instanciating a
variety of derived-class instances.

I believe another important things is that storing pointers would
not result in default constructors being called or required.
Default constructors are only required if you actually use them, like
in resize().
Also, using a pointer would not call a copy constructor when placing
the object into the container.
True. You shouldn't store objects that are expensive to copy in a
standard container.

On the other hand, the destructor for the elements is not called when
an element is removed, or when the vectors is destructed. That might
add additional code and book keeping elsewhere in the program.
Bo Persson
Aug 28 '06 #15
On Tue, 29 Aug 2006 00:58:37 +0200, "Bo Persson" <bo*@gmb.dkwrote:
>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
Aug 29 '06 #16

Roland Pibinger wrote:
Please take a look at other container libraries apart from STL (Rogue
Wave, MFC, Qt3 ...). They have containers for pointers and containers
for values. It's just STL that's 'value only'. Rouge Wave e.g. has a
RWTPtrDlist for pointers and a RWTValDlist vor values. The OP's
questions is valid.
and then there is, of course, boost:

http://www.boost.org/libs/ptr_contai...container.html

I'm not sure if this is the same one that was in TheSourceProject or a
different one. I haven't taken time to look. The boost implementation
uses "thin templates" i.e. they do the implementation with void*
pointers and cast both ways. Not sure if that is always safe in a
mutliple-inheritance situation, but it can have its advantages, i.e.
far less code generation and even allows you to compile some of it into
object code to be linked in.

Aug 29 '06 #17
I V
On Tue, 29 Aug 2006 03:30:08 -0700, Earl Purple wrote:
and then there is, of course, boost:
[snip]

Not to mention boost::indirect_iterator,
http://boost.org/libs/iterator/doc/i..._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).

Aug 30 '06 #18
On Tue, 29 Aug 2006 22:07:04 -0700, I V <wr******@gmail.comwrote:
>On Tue, 29 Aug 2006 03:30:08 -0700, Earl Purple wrote:
Not to mention boost::indirect_iterator,
http://boost.org/libs/iterator/doc/i..._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.
>(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



Aug 30 '06 #19

Roland Pibinger wrote:
Why should a container for pointers be usable only for objects
allocated with new? Why is such a container supposed to delete
contained objects?
It shouldn't have to. But there are containers for those that don't.
When I saw boost's ptr_vector my first impression was that perhaps
there should have been a custom deleter option, although the
custom-deleter would need to be the same for every object in the
vector.

If you want custom deleters for each pointer then use vector<
shared_ptr >.
And for sort you have the option of passing ni your own predicate that
can do *iter1 < *iter2
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).
It's not a design flaw it's a design decision. You use that collection
when you want that functionality. When you don't, you use a different
one. It enables you to use std::generate to fill the collection where
std::generate calls new.
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.
In the absence of real garbage collection, you must provide ownership
semantics. And assuming you don't want to use shared_ptr, using a
collection to handle the it for you is not unreasonable.

I do think though that there should be an option of a custom deleter,
albeit one deleter for every item in the collection so there is no
option to mix and match. Not unless the deleter is smart enough to do
that, that is.

Aug 30 '06 #20

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Darkay Li | last post by:
I have try to create an allocator like follow: // the type of allocator must be some kind of pointer template <class Type> class PointerAllocator : public std::allocator<Type> { public: typedef...
3
by: LinusLee | last post by:
class CAnalyzer { // attribute private: public: // behavior private: void NullFunc(NODE *pNode); void TraverseNode(NODE* pNode, void (*preFunc)(NODE *node), void (*postFunc)(NODE *node));
4
by: Carsten Spieß | last post by:
Hello all, i have a problem with a template constructor I reduced my code to the following (compiled with gcc 2.7.2) to show my problem: // a base class class Base{}; // two derived...
2
by: Brandon | last post by:
In a templated class I wrote, there is a public typedef for a function pointer. The class has an instance of the function pointer as a private member. That pointer is declared as static so I need...
1
by: vwbora | last post by:
Hi, Can you please tell me how I can obtain a pointer to a base class from a variable which is a reference to a derived class. As an example, I have a variable which is a reference to a...
4
by: Daniel Aarno | last post by:
Consider the following code: typedef int A; class B { public: B(A& var) : m_var(var) {} virtual ~B() {} protected:
11
by: codebloatation | last post by:
I know how to use references but i DO not get WHY they exist other than to add to the language. Are they actually needed for anything?
6
by: joosteto | last post by:
Subject: pointer to any member function of any class. The "C++ FAQ Lite" explains how to hand a pointer to a member function to a signal handler etc, but only to a static function (33.2), to a...
11
by: Brian | last post by:
Dear Programmers, I have a class with a pointer to an array. In the destructor, I just freed this pointer. A problem happens if I define a reference to a vector of this kind of class. The...
8
by: mathieu | last post by:
Hi there I have implemented a very simple smartpointer class (invasive design). And I was wondering what should be the natural API when using those in a Container. I choose to define the...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.