a pointer to a derived class problem

  • Thread starter stefven blonqhern
  • Start date
S

stefven blonqhern

hello all, having a problem with derived classes. i'll show by
pseudo code example. first the base class and derived classes:

class Shape { // base class for all shapes
public:
virtual void Draw() {// draw code here}
};

class Square : public Shape {// etc};
class Circle : public Shape {// etc};
class Triangle : public Shape {// etc};

then I create another class called MyClass which has a member function
ChangeShape which creates a new Shape object and assigns a pointer to
it. the member function Render is being called constantly in the
background.

class MyClass {
public:

void ChangeShape(int shape) {
// if shape = 0 then sh = Square, 1 = Circle, 2 = Triangle
// but for the sake of brevity i'll just use a square
sh = Square();
shPtr = □
}

void Render() {shPtr->Draw};

Shape sh;
Shape* shPtr;
};

obviously whenever i access the member function Draw through the
Shape* (shPtr) it always calls the member for Shape not Square because
sh is of type Shape. all this might sound ridiculous? can i assign
derived classes to sh and keep the derived class type instead of them
being converted to the base class type? my implementation is somewhat
limited by the plug-in architecture i must work within.

TIA for any help, hope i explained that clearly.

Stephen.
 
V

Victor Bazarov

stefven said:
hello all, having a problem with derived classes. i'll show by
pseudo code example. first the base class and derived classes:

class Shape { // base class for all shapes
public:
virtual void Draw() {// draw code here}
};

class Square : public Shape {// etc};
class Circle : public Shape {// etc};
class Triangle : public Shape {// etc};

then I create another class called MyClass which has a member function
ChangeShape which creates a new Shape object and assigns a pointer to
it. the member function Render is being called constantly in the
background.

class MyClass {
public:

void ChangeShape(int shape) {
// if shape = 0 then sh = Square, 1 = Circle, 2 = Triangle
// but for the sake of brevity i'll just use a square
sh = Square();

That's a VERY BAD IDEA(tm). What happens is called "slicing". The
object 'sh' is of the type 'Shape' and it is assigned only the base
class subobject from the temporary 'Square'. All the characteristics
(polymorphic included) are lost.
shPtr = □

That's not even C++. Did you mean

shPtr = &sh;

?
}

void Render() {shPtr->Draw};

Shape sh;
Shape* shPtr;
};

obviously whenever i access the member function Draw through the
Shape* (shPtr) it always calls the member for Shape not Square because
sh is of type Shape. all this might sound ridiculous?

Is that a question.
can i assign
derived classes to sh and keep the derived class type instead of them
being converted to the base class type?

No. Read up on "slicing".
my implementation is somewhat
limited by the plug-in architecture i must work within.

What does that mean?

V
 
S

stefven blonqhern

That's a VERY BAD IDEA(tm).

i suspected as much and Bjarne Stroustrup (Special Edition) has just
confirmed it.
What happens is called "slicing". The
object 'sh' is of the type 'Shape' and it is assigned only the base
class subobject from the temporary 'Square'. All the characteristics
(polymorphic included) are lost.


That's not even C++. Did you mean

shPtr = &sh;

yes i meant shPtr = &sh;

so what i'd need is something like:

Square shSqr;
Circle shCir;
Triangle shTri;

in the MyClass definition. then i can just assign shPtr to the
appropriate object after i create it in ChangeShape. this feels a
little clumsy though and wasteful since i will be creating many
objects that potentially won't get used.
What does that mean?

just means that i don't have free reign to completely rework the
design. what i am doing has to fit into something else so to speak.

thanks for the help, Stephen.
 
V

Victor Bazarov

stefven said:
[..]
so what i'd need is something like:

Square shSqr;
Circle shCir;
Triangle shTri;

in the MyClass definition. then i can just assign shPtr to the
appropriate object after i create it in ChangeShape. this feels a
little clumsy though and wasteful since i will be creating many
objects that potentially won't get used.

No, a better idea is to create your 'Square' or 'Circle' or whatever
*dynamically*, and only store the pointer to it:

shPtr = new Square; // for example

Don't store the object, it's unnecessary to duplicate it. The real
object will be created in the free store. You will need to dispose
of it when you don't have the need for it any longer. Make sure
your 'Shape' class declares the destructor as 'virtual'.

V
 
S

stefven blonqhern

that works well. (respect to Victor Bazarov). this is what i was
attempting to do yesterday but i made a big hash of it.

thanks, Stephen.

stefven said:
[..]
so what i'd need is something like:
Square shSqr;
Circle shCir;
Triangle shTri;
in the MyClass definition. then i can just assign shPtr to the
appropriate object after i create it in ChangeShape. this feels a
little clumsy though and wasteful since i will be creating many
objects that potentially won't get used.

No, a better idea is to create your 'Square' or 'Circle' or whatever
*dynamically*, and only store the pointer to it:

shPtr = new Square; // for example

Don't store the object, it's unnecessary to duplicate it. The real
object will be created in the free store. You will need to dispose
of it when you don't have the need for it any longer. Make sure
your 'Shape' class declares the destructor as 'virtual'.

V
 
S

stefven blonqhern

Don't store the object, it's unnecessary to duplicate it. The real
object will be created in the free store. You will need to dispose
of it when you don't have the need for it any longer. Make sure
your 'Shape' class declares the destructor as 'virtual'.

Once i reassign the pointer will unused objects not get garbage
collected? I'd prefer to err on the side of caution anyway but just
curious.

Stephen
 
B

BobR

stefven blonqhern said:
Once i reassign the pointer will unused objects not get garbage
collected?

Don't know. Show your definition of 'garbage collected'.
I'd prefer to err on the side of caution anyway but just
curious.
Stephen

// includes here

class Shape{ public:
virtual ~Shape(){} // required for base
};

class Circle : public Shape{ public:
Circle(){}
};

{ // main() or?
using std::cout; // for NG post
Shape *dummy( 0 );
std::vector<Shape*> vecShapes( 10, dummy );
vecShapes.at( 2 ) = new Circle();
// .... use vecShapes ....
for( size_t i(0); i < vecShapes.size(); ++i){
if( vecShapes.at( i ) ){
cout<<"deleting vecShapes.at("<<i<<")"<<std::endl;
delete vecShapes.at( i );
}
} // for(i)
}
// out: deleting vecShapes.at(2)
 
?

=?ISO-8859-1?Q?Erik_Wikstr=F6m?=

Once i reassign the pointer will unused objects not get garbage
collected? I'd prefer to err on the side of caution anyway but just
curious.

Standard C++ does not come with a garbage collector, you must free all
memory allocated with new manually (using delete). There are garbage
collectors available for C++ if you want one, but I'd recommend to not
use one while learning (if nothing else to learn ways to avoid needing one).
 
S

stefven blonqhern

Standard C++ does not come with a garbage collector, you must free all
memory allocated with new manually (using delete). There are garbage
collectors available for C++ if you want one, but I'd recommend to not
use one while learning (if nothing else to learn ways to avoid needing one).

"if a garbage collector is present, the deletes can be omitted in most
cases" Stroustrup

okay, i'm quite surprised that standard c++ doesn't have a garbage
collector. i'm with you though on the idea of not using one even if
just to learn why? this C++ gets better every day.

Stephen.
 
J

James Kanze

Once i reassign the pointer will unused objects not get garbage
collected? I'd prefer to err on the side of caution anyway but just
curious.

Only if you've installed and activated garbage collection. It's
not active by default, and it's only available as a third party
add-on with many compilers. (Try searching for the Boehm
collector on the web. That's the one I use: it works well, and
isn't too difficult to install.)
 
J

James Kanze

"if a garbage collector is present, the deletes can be omitted
in most cases" Stroustrup
okay, i'm quite surprised that standard c++ doesn't have a garbage
collector.

History. When Stroustrup was developing C++, garbage collection
technology wasn't fully mature, so he designed the language not
to depend on it. Today, of course, the situation is different,
but it takes considerable time and effort to get those sort of
things through the standard's committee.
i'm with you though on the idea of not using one even if
just to learn why?

As a general rule: if you can't write correct code without
garbage collection, you won't be able to write it with. There
is no silver bullet, and garbage collection doesn't free you
from the design issues concerning lifetime of object. On the
other hand, if you know how to write correct code without
garbage collection, you'll also know how to write it with
garbage collection, and using garbage collection will mean less
work for you.

Perhaps the best analogy I can come up with: if you don't know
the difference between dirty dishes and clean ones, a dishwasher
won't teach it to you. But if you do, using a dishwasher is a
hell of a lot less work than washing dishes by hand.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top