Sign in to follow this  

Is this a good practice?

This topic is 4709 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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!

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 4709 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this