Style question involving inheritance

Discussion in 'C++' started by Russell Silva, Jul 26, 2003.

  1. 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
     
    Russell Silva, Jul 26, 2003
    #1
    1. Advertising

  2. Alf P. Steinbach wrote:

    > (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
     
    Russell Silva, Jul 26, 2003
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    6
    Views:
    422
    Ian T
    Dec 10, 2004
  2. Replies:
    1
    Views:
    811
    Bertilo Wennergren
    Nov 24, 2003
  3. darkstorm
    Replies:
    3
    Views:
    367
    Malte Starostik
    Mar 29, 2005
  4. Replies:
    0
    Views:
    347
  5. Ken Varn
    Replies:
    0
    Views:
    526
    Ken Varn
    Apr 26, 2004
Loading...

Share This Page