Is this a good practice?

Started by
2 comments, last by JimPrice 19 years, 3 months ago
I have a "mother" class, lets call it cMother. Now, there is a series of different "son" classes, some of them having unique variables. I store all the objects of these classes in a vector<cMother> . Now, at one point in my program, I need to access some variables that exist only in one son class. Would it be a good idea to give cMother a ReturnValue() function that, by default it would return null, but in case of that one son class, it would re-defined returning the actual variable? Something like this:

class cMother
{
 virtual int GetA() {return 0;};
 virtual int GetB() {return 0;};
};

class cSon1 : public cMother
{
 int A;
 int GetA() {return A;};
};

class cSon2 : public cMother
{
 int B;
 int GetB() {return B;};
};

Naturally, I understand there is no true "good" or "bad" solution, I was just wondering if this method would be frowned upon... Otherwise, what could I use? (cSon2*)SomeMother->B ? Unfortunately, making the function that needs these values a function inside the son class doesn't work in my case... thanks for the tips!
Comrade, Listen! The Glorious Commonwealth's first Airship has been compromised! Who is the saboteur? Who can be saved? Uncover what the passengers are hiding and write the grisly conclusion of its final hours in an open-ended, player-driven adventure. Dziekujemy! -- Karaski: What Goes Up...
Advertisement
Generally speaking, where you have a list of instances of a base class, you should not do anything with that list that requires them to be any particular derived class.

One pretty good way to resolve this is to just keep another, seperate list of pointers to these objects, of the derived type. In your case, you would have a list of pointers to all the instances of cMother, but you would also have a seperate list of pointers to cSon1 (of type cSon*[] or vector<cSon*> or whatever) which you use when you need to operate on the cSon objects in a manner specific to that class, and a seperate list of pointers to cSon2 instances. You can create these lists pretty neatly by having the derived classes register themselves with a manager class in the constructor.

In response to the original question of whether the slightly awkward polymorphic solution is good practice: I'd say no, because it's not scalable. It's fine when you have one superclass and two subclasses, but as the class heirarchy grows you will find that more and more derived-class-specific API percolates up to the base class, resulting in the base class containing a whole host of methods which are slightly nonsensical in the context of what the base class is actually meant to represent, and generally looking like a mess.
Harry.
That is a reasonable solution as long as it makes sense for cMother to have GetA and GetB functions, regardless of what classes are derived from it.

For example, if you later create a derived class cSon3 with the members C and GetC(), and doing that requires you to modify the cMother class by adding a virtual GetC function, then you have definitely gone down the wrong path.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:
Otherwise, what could I use? (cSon2*)SomeMother->B ?


If you do want to do something like this:

The C++ way is to use dynamic_cast, instead of a straight C-style cast. A C-cast, as you've used, just assumes you know what you're talking about, and will attempt to cast to the requested form irrespective of consequences - it's up to the programmer to ensure they're doing the right thing.

A dynamic_cast on the other hand fails if the object being cast to is not actually that type of object. Hence, you use something like:

if(cSon2* thisSon = dynamic_cast<cSon2*>(SomeMother))
thisSon->B;

This of course assumes that SomeMother is a cMother* (and also assumes that you've mistyped struct as class in your code; otherwise you'll have issues....).

Jim.

This topic is closed to new replies.

Advertisement