Solved

Need Advice ... Can I have a class member look like another type to not loose extra memory space

Posted on 2001-07-24
6
211 Views
Last Modified: 2010-04-02
This probably is a stupid question but here goes ...

E.g. (simplified)

Base
 |
Derived1
 |-------------------|--------------|
Derived11         Derived12       Derived13


Derived1 has a member :
Derived1 *DerivedParent ;

And Derived11, 12 and 13 make use of this DerivedParent to get certain data.

I now come to the conclusion that maybe I should have placed a Parent in Base :
Base *Parent
because other classes derived from Base could use the member too + it would make creating a special other class easier too.

To not have to rewrite all the classes that now DerivedParent as a Derived class instead of Base class I was wondering if I could put the member in Base but have it look like all's the same ???

I can have a Parent in Base AND Derived1
and in the Derived constructor write :
Base::Parent = Parent ;

But then I would have two pointers instead of one (I can miss the extra 4 bytes per object)

So I was wondering if it is not possble to have the Parent in Base but some sort of ???don't know??? in Derived1 that doesn't take physical space and looks like a pointer to Derived1. ???

I could also In Derived1 change DerivedParent to a function DerivedParent() (still re-write required but minimal).
But then I would have to dynamic_cast the Base pointer :

Derived1 *DerivedParent()
 {
 return dynamic_cast<DerivedParent*>(Base::Parent) ;
 }

But then I ask myself dynamic_cast is this slow ??
What does it take for code to constantly check with dynamic_cast ??

Hope this all makes sense.
I'm new to OOP but I'm learning !!!


0
Comment
Question by:sneeuw
  • 4
  • 2
6 Comments
 
LVL 22

Expert Comment

by:nietod
ID: 6315460
>>  if I could put the member in Base but have it look like all's the same ???
The real question is how does this additional pointer member affect the interface of the Base class.  If it has no affect ont he interface, then yes, the base class still looks the same If the pointer affects the interface, then the base class has changed, you then need to look more closely at how it has changed to see what effect this has.

For example, is the member A) private or B) protected/public.   If A, then it doesn't affect the interface, if B then it is may be a small change to the interface.  The next question, if B, is does code outside of the base class need to change this data member?  If so this may be an area of problem  You need to consider what code needs to change it and how much trouble it will be to alter the code so that it does change it.

Next consider if there are functiosn that A) obtain and B) set the value of the member.  If A, it is a slight affect on the interface, but that should not matter.  If B, that is a bigger effect.  Again you need to consider if code outisde of the class will need to set this data member.  if so, this could be a problem   Again think about how much trouble it will be to insure that this data member is set correctly

Next consider if there are existing functions outside of the base class, probably virtual functions, but maybe not, that will be affected by this data member.  i.e. will then need to use this data member in their implimentaition?   if so, again you need to consider how hard it will be to make this change.

continues
0
 
LVL 22

Expert Comment

by:nietod
ID: 6315492
>> I can have a Parent in Base AND Derived1
>> and in the Derived constructor write :
>> Base::Parent = Parent ;
What about Derived2? and 3?

Do these need this data member?  If not, then it definitely suggests that adding it to Base is a mistake.  

If that is the case, that Base needs it and Derived1 needs it, but not 2 and 3, then consider an alternative.    Leave Base as is. i.e don't add this data member to Base.  Then derive a new class from Base, lets call it Base2.  Add this data member to Base2.  Then derive Derive1 from Base2, so Derive and Base 2 both have this new data member.  but derive Derived2 and Derived3 from Base, not Base1, so these don't have this additional data member.

>> So I was wondering if it is not possble to have the Parent in Base but
>> some sort of ???don't know??? in Derived1 that doesn't take physical
>> space and looks like a pointer to Derived1. ???
No.  But wasted space is probalby the least significant problem for you to consider.  You need to consider if this change leands to illogical interfaces or difficult source code changes.  By illogical interfaces, I mean things like will the Derived2 class have a function that sets this data member, yet it never uses this data meber for anything?  That is messy and can come back to haunt you.

>> But then I ask myself dynamic_cast is this slow ??
>> What does it take for code to constantly check with dynamic_cast ??
Its slow compared to other casts,  In fact MUCH slower,  but still its not really that slow.  You should be able to peroform 1000s of them in a second (probalby 10s of 1000s or 100s of 1000s really).  How often doyou really need to do this cast?  probably not so often that the extra time will matter.
0
 

Author Comment

by:sneeuw
ID: 6316614
Hi nietod,

I guess you're right.
Parent shouldn't be really in Base

The problem I face is that Base has several types of decendants each with their own kind of Parent (the Parent types differ).

I was now writing a piece of code and was looking for some way to make it all look the same so that I could use a pointer to Base to work from instead of having to check the type of Object and then decide on the type of parent.

For the same reason I wanted a function and some additional variables in Base so that I could generalise working with the different decendants of Base.
However, this then looks 'stupid' as the function resides in Base but the actual Parent resides in the derived class.
e.g.  
Base::DoSomethingWithParent(void) ;

But in Base then the function would be virtual or do nothing and the actual decendants do the work.

 
0
Enabling OSINT in Activity Based Intelligence

Activity based intelligence (ABI) requires access to all available sources of data. Recorded Future allows analysts to observe structured data on the open, deep, and dark web.

 
LVL 22

Expert Comment

by:nietod
ID: 6316784
>> The problem I face is that Base has several types of
>> decendants each with their own kind of Parent (the
>> Parent types differ).
Sometimes that means that the base class should not contain the pointer and sometimes it does.

For example consider a window object hearachy--I hope you are familar with windows.   Each window has a parent window--except top level windows.  so each window object has a pointer to its parent window object, int op-levle windows the pointer is NULL.   For most windows the parent window can be of any class type, so the parent window object could be any type derived from the base window class (WindowBase, say).  But for some windows the parent has to be of a particular class type.  For example, a MDI Child window has to have a parent that is a MDI Client window.  But not every window has a parent that is a MDI client window, so the parent window pointer stored in the base class, must point toa base class window object, not a MDI client window object.   This means that the MDIi child window object will at times have to cast its parent window object from a base class to a MDI client window.   But that only has to be done when features specific to the MDI client are needed.    In this case It would nto make sense to remove the parent pointer from the base class, as I suggested above, because virtually every single window object needs this pointer and most of the times it is used, it is used by the base class.  i.e. when a child window is created, moved, sized, painted, and 100s fo other fucntions  this pointer is needed.  

>> The problem I face is that Base has several types of decendants
>> each with their own kind of Parent (the Parent types differ).
Then the question you need to ask yourself is how much is common to all the classes regarding this pointer?   For example, are there lots of operations performed by the base class that will need this pointer.  if so, you might want to leave it in the base class and downcast.  On the other hand, if the use fo this pointer is pretty specific to the derived classes, and differes from class to class, then pt it in the derived class.   Finally there is a 3rd option.  Store the pointer in the derived class.  This allows the derived class to store it as the exact type needed (like in my example, it could be a pointer to a MDI client window obkect for some classes).   This also allows the derived classes to informace retraints n the pointer, alllowing it to be set in cenrtain ways etc.    Then if the base class needs the pointer for common operations, it cann call a virtual procedure that returns the pointer (typed as a pointer to some base class, if needed)   Each of the derived classes have to impliment this procedure to return the pointer they store.   This can solve your issues with

Base::DoSomethingWithParent(void)

The derived classes can store pointers to parents of non-BAse types, as is appropriate for them.  For their operations, they are able to use a pointer of the derived class type, as appropriate for them and without casting.   But for "common" operations, the base class can get a hold of the pointer to do work tht is common to all classes.
0
 

Author Comment

by:sneeuw
ID: 6316821
> Finally there is a 3rd option ...

Yes, this is the idea I'm playing with now.
So this wouldn't be regarded as a 'bad' way of making use of OOP ?

I mean ... the first example (MDI vs. Base) makes a lot of sense but then I would have to change a lot and do A LOT of casting in the derived classes.
0
 
LVL 22

Accepted Solution

by:
nietod earned 80 total points
ID: 6317003
>> So this wouldn't be regarded as a 'bad' way of making use of OOP ?
Not at all.   its not uncommon for a base class to provide a basic implimentation of an algorithm, but at times this algorithm needs to call a vitual function to let the derived class "have input"  This occurs in one of two ways.  either the base class cals a virtual function that instructs the derived class to perform some sort of action, or the base class calls a virtual functin that allows the derived class to return information or "instructions" to the base class.

The reverse of this spproach is used too.  You might have a virtual function that performs some algorithm  that is provided by the derived class.  But at some point in the derived class's processing of the function it might calll the base class version of the function to do some of the work.
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now