Style question involving inheritance

R

Russell Silva

I have a program set up something like this:

class A {
//(...)
}

class B : public A {
//(...)
public:
void not_in_class_A();
}

class usesA {
//(...)
protected:
A A_to_be_used;
}

class usesB : public usesA {
//(...)
void init(B B_to_be_used) {
A_to_be_used = B_to_be_used;
}

void do_something () {
A_to_be_used.not_in_class_A(); //error!
}
}

Assume that usesB::init(B_to_be_used) is the only method that modifies
the A A_to_be_used in a usesB object.

The above error can be easily fixed, if I'm not mistaken, using a cast:

((B) A_to_be_used).not_in_class_A();

but Bjarne Stroustrup says "casts are generally best avoided"
(http://www.research.att.com/~bs/bs_faq2.html#static-cast). I'm trying
to improve my C++ style, so I'm looking for either another solution to
the problem (namely, call A_to_be_used.not_in_class_A() somehow) or
assurance that this is an instance in which casting is stylistically
appropriate.

Thanks in advance.

-Russell Silva
 
R

Russell Silva

Alf said:
(1)
An init-method instead of a constructor is very bad style.

Thank you, I didn't know that. A resulting question, however: I often
use init() methods when an object might need to be reinitialized (i.e.
most or all of its member variables reassigned). Is this still poor style?
(7)
The problem is something else. To find what the problem is (I don't
know what it is), think about _why_ you want that A_to_be_used object
defined high up in the hierarchy. A more concrete example might
help, since you've abstracted a technical detail of a non-solution.

*sighs* I had a feeling that my problem extended beyond one line of code.

Here's what I'm doing: (edited for relevance)

class Imp_DrawableBase { //formerly known as class A
protected:
vector<Imp_SpriteFrame> images;
void add(Imp_SpriteFrame& to_add);

public:
SDL_Surface* get_image(string to_get);
SDL_Surface* get_image(int to_get);
}

class Imp_SpriteBase : Imp_DrawableBase {//formerly known as class B
protected:
vector<Imp_SpriteSequenceBase> sequences;
void add(Imp_SpriteSequenceBase& to_add);

public:
Imp_SpriteSequenceBase& get_sequence(string to_get);
Imp_SpriteSequenceBase& get_sequence(int to_get); }

class Imp_Drawable { //formerly known as class usesA
protected:
SDL_Rect destrect; //position
Imp_DrawableBase* drawablebase;

int current_imagenum;
SDL_Surface* current_image;

bool initialized;

public:
virtual int draw();
int set_image(int imagenum);
Imp_Drawable();
virtual void init (Imp_DrawableBase& spritebase);
};


class Imp_Sprite : Imp_Drawable { //formerly known as class usesB
protected:
Imp_SpriteSequence current_sequence;

public:
int draw();
void set_sequence(string set_to);
Imp_Sprite();
void init (Imp_SpriteBase* spritebase);
};

This is an approximation; the code is not yet finished and it still
suffers from (as I just learned) stylistically inappropriate init()
methods. Still, the general pattern is there.

What I'm doing is creating classes for the display of static images and
sprites. Both sprites and static images require the same image
information (some number of images to display), but sprites also require
information on how to display the images in some order to form an animation.

Now I may want to display a given static image or sprite at multiple
places on the screen simultaneously. I thus create classes with suffix
Base that cache the information needed for display, and separate classes
to actually display the images. Thus, I can instantiate many objects
that all rely on the same Base information, saving memory. The
Imp_DrawableBase class contains a vector of the different images I wish
to display. The Imp_SpriteBase class, child of Imp_DrawableBase,
contains a vector of Imp_SpriteSequenceBase (not shown) that contain
information on how I wish the sprite to animate.

An Imp_Drawable object uses the images cached in a Imp_DrawableBase
object to draw static images on the screen. An Imp_Sprite object uses
both the cached images (from Imp_DrawableBase) and the cached sequences
(from Imp_SpriteBase) to draw animating sprites on the screen.

Which brings me to my original problem: I need Imp_Sprite objects to be
able to call get_sequence from Imp_SpriteBase. Some sort of cast would
work, especially since I use a pointer in my code, solving both the
slicing and the cast problem. But as has been pointed out,
stylistically I likely have already transgressed, but I'm not sure how
or what a good way to correct it might be.

If I've crossed the line into offtopic (from c++ style to 2d image
manipulation/gamemaking) limbo, my apologies.

Thanks in advance.

-Russell Silva
 

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,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top