Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Calling Base-Class functions

Posted on 1999-06-29
12
Medium Priority
?
224 Views
Last Modified: 2010-04-02
I'm working on an app that goes OO naturally, due to the hierarchical nature of the data.  What I'm having a problem with is where to stick some of the code.  I have an abstract base class (call it A) that B and C inherit from.  What I'd like to do is have code in A that is shared by both B and C.  I currently have a "display" function in B and C that share a pretty big chunk of initialization code.  What seems natural to me is to have a virtual "display" in A that does this setup, then call that from B and C before running their own code.  Is this possible?  Is there a better way?  Do I have to call the function something different in A?
0
Comment
Question by:Floater
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
  • 3
12 Comments
 
LVL 3

Accepted Solution

by:
Shay050799 earned 750 total points
ID: 1198742
that exectly the idea of OOP.
why don't u put that initialization in the A constructor, but:
1) make sure that all the variables are Protected which mean: private for outof the hirarchy but public to the hirarchy classes
2) make sure A doesn't have any pure vurtual other functions.

make the A destructor Virtual, and do all the Uninitialize in there, that way u won't need to call the derived destructor.

let me know if you nee anything else

shay
0
 

Author Comment

by:Floater
ID: 1198743
The initialization stuff isn't something that can go in the constructor... it's called at every "tick".  How does that change the answer?

Why can't A have pure virtuals if I don't want to instantiate it?

Why is the destructor virtual?
0
 
LVL 3

Expert Comment

by:Shay050799
ID: 1198744
1 )what do u mean by "tick"  ?
2) u want to call some A function to do something right ? so u need to implement A in someway right, so A can't be Pure virtual, u can do it virtual not pure virtual.
pure virtual it mean that all its function declare like that:
virtual void Foo1()=0;
virtual int Foo2(int,char*)=0
etc...

it calls Interface.
3) when u declare you Base destructor as virtual it gurantee to be called after u destroy one of its derived class declare it the following way:

virtual ~A()

and u all set. now all the UnInitialize is in this destructor which will be called everytime one of the derived class destroy
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 

Author Comment

by:Floater
ID: 1198745
I think I got it working...
"Tick" means the function is called about 100 times/sec, and the initialization stuff in A should happen each time.

What I'm doing is in A:
virtual output() {/* Init stuff */}

In B/C:
virtual output() {
    A::output()
    ...
}

Last question, unless theres a problem w/ the above:
If I do a virtual destructor, it automatically calls the base class's destructor for me?  This happens before the derived, correct?  And this doesn't happen for other, non-destructor functions?
0
 
LVL 3

Expert Comment

by:Shay050799
ID: 1198746
u don't have to declare Output in B do this
class A
{
public:

      virtual void Init() {cout<<"A::Init";}
      virtual ~A() {cout<<"A::Detructor";}
};
class B:public A
{
};

void main(void)
{
      A* a;
      a=new B;
      a->Init();
}

no the B destructor called first but than it calles the base class destructor
0
 
LVL 3

Expert Comment

by:Shay050799
ID: 1198747
it depends on the way u declare it.
if u declare it like that:
A* a=new B
it never calles B destructor


0
 

Author Comment

by:Floater
ID: 1198748
I know I don't have to, but the point was to share the output() code from A in both B and C's output() function as the beginning segment.  Thanks for the help.

0
 
LVL 3

Expert Comment

by:Shay050799
ID: 1198749
it does share, call Output from B or C it automatically called the A function thats the idea of OO
0
 
LVL 22

Expert Comment

by:nietod
ID: 1198750
>> Why can't A have pure virtuals if I don't want to instantiate it?

>>u want to call some A function to do something right ?
>> so u need to implement A in someway right, so A can't be
>> Pure virtual, u can do it virtual not pure virtual.
>> pure virtual it mean that all its function declare like that:
>> virtual void Foo1()=0;
No.  First of all A can be a pure abstract class in this case, and probably should be.  Secondly a pure virtual function may have an implimentation, so the output function is a good candidate for being pure-virtual.

>> when u declare you Base destructor as
>> virtual it gurantee to be called after u destroy
>> one of its derived class
It is guaranteed to be called anyways.  That is, it will be called if it is virtual or not.  Making a destructor guarantees that the DERIVED class destructors, not the BASE class destructors will be called.

>> it does share, call Output from B or C it automatically
>> called the A function thats the idea of OO
Not automatically.  You must make it do so.  floater's code does so.  
0
 
LVL 22

Expert Comment

by:nietod
ID: 1198751
>> I know I don't have to, but the point was to share
>> the output() code from A in both B and C's output()
>> function as the beginning segment
Shay, you want to say something on that point?  that was the question, right?

floater there are two approaches to this sort of problem.  

One is the approach you took where the derived class has a function that calls on the base class version of the function to perform part of the processing.  In your case the B and C classes override the output() function and within these overrides they call on the A class's version of the function.  In this case the function does not have to be virtual, although it may be a good idea for it to be so, it just depends on how this will be used.

The other approach is to define the function in the base class only and to have this function perform the "shared" processing.  Then have this function call on one or more virtual "notification" functions.  These notification functions would be overidden in the derived class and would allow those classes to perform their class-specific processing.

Which approach to take will depend on the circumstances in which the code is being used.  However I find that the 2nd approach tends to be better in a majority of the cases.
0
 

Author Comment

by:Floater
ID: 1198752
The situation is for an OpenGL rendering interface;  Object A is a root "3D object" class, and B and C are specific object types w/different behaviors.  I want to put stuff generic to 3D object display into A's display code, so it does the startup stuff like turning on or off lighting based on the flags in A.  The reason I'm leaning toward the first way you describe instead of notification functions is that later, I want to call display() on a list of type A*, where the objects are B's and C's.  This will call the B and C display(), and they'll call the parent's display() for the shared code.

Is there some advantage to notification functions over this method?  They seem functionally equivalent initially.

(BTW, I already gave out points for this one, after I figured out the parent calling.  Is there some way I can send you points for the helpful comments?)
0
 
LVL 22

Expert Comment

by:nietod
ID: 1198753
>> Is there some advantage to notification
>> functions over this method?
either will work--they are interchangable.  But one may be better than the other in terms of how easy they are to maintain over time (as the program's needs change.)  For example, in your case you always want the base clase (A) version fo the procedure to be called to perform some "set-up" steps before the derived class begins its work.  Now what if you later add a class D, but in D's version of output, you forget to call the base class version of output.? opps!  If you used a design like

class A
{
   virtual void OutputNotification() {} =0;
public:
   void output()
   {
       // Do setup stuff.
      OutputNotification();
   }
};

Then when you add new classes, they only need to redefine OutputNotification (which they must do) and the setup steps will automatically be performed by the Output procedure.  

Now this addvantage is also its dissadvantage, what if you add class E and in this class you don't want the setup steps performed?  There are two ways around that, 1) use the design you suggested and make sure to call the base class version when needed, or 2) use the design I suggested above AND make the output function virtual as well.  Then the B, C, and D classes only need to redefine the notification function and are assured that they get the propper setup performed automatically, and the E class can redefine the output function so that no setup (or different setup) is done.  This second option is very powerful, but may add a lot of virtual functions to the class that aren't completely necessary.

>> I already gave out points for this one, after
>> I figured out the parent calling
In the future make sure not to grade answers that are incorrect or unhelpful (if you can tell they are incorrect...)  If an expert is not being helpful--don't reward him/her.

>> Is there some way I can send you
>> points for the helpful comments
That's alright.  I just didn't want to see you left with a lot of wrong information.
0

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
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 learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

670 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