Solved

Inheritance and overloading with a twist

Posted on 1998-07-27
18
373 Views
Last Modified: 2010-04-02
I'm trying to get 2 classes to work together.  The first class is called from the main code by creating an object:

CWCA  obj1(record_entry);

class CWCA
{
friend ostream& operator <<(ostream& str, const CWCA& W)
            {return str << "Mission ID: WCA\n" << "MSU WCA ID is: " <<
             W.WCA_ID << endl << "WCA Cmd is: " << W.state << endl <<
             W.Common_Data ;
            }
public:
      CWCA(unsigned short entry[])
      {CCommon Common_Data(entry);WCA_ID = entry[1] >> 8; WCA_Cmd = entry[1] & 255;
       if(WCA_Cmd == 0) state = "Active";
            else state = "Inactive";
      }
private:
      short WCA_ID;
      short WCA_Cmd;
      char* state;
};

As you can see there is an attempt to create a CCommon object from within the CWCA class( CCommon is a class I've defined in the same header file that also overloads the "<<" operator).  Anyway, back in the main function I read in an array of type short values that need to be accessible to both classes, so I passed the array to the CWCA class.  My objective is to be able to output ( << )  the Common_Data object from the CWCA class by including it in the "friend ostream& operator <<()" function as attempted above.  This way in the main function when I go to output obj1 with the following line of code:

cout << obj1;

it is in reality outputting from both the CWCA and CCommon classes.  Another way to look at it is that I'm trying to go from this code in main()

CWCA obj1(record_entry);
cout << obj1;

CCommon obj2(record_entry);
cout << obj2;

to this code

CWCA obj1(record_entry);
cout << obj1;

Also I need for the array passed into the CWCA class to have scope in the CCommon class.  Below, I went ahead and included the CCommon class:

class CCommon
{
friend ostream& operator <<(ostream& str, const CCommon& C)
            {return str << "Day " << C.RecDay << " of " << C.RecMonth << "/" <<
             C.RecYear << " at " << C.RecUTC_Time << " seconds." << endl <<
             "Lat: " << C.lof2.FltMSULat << "  " << C.state << endl <<
             "Long: " << C.lof.FltMSULong << "  " << C.state2 << endl;
            }
public:
      CCommon(unsigned short entry[])
      {RecMonth = entry[10] & 255; RecYear = entry[10] >> 8;
       RecDay = entry[9]; RecUTC_Time = entry[11] << 16; RecUTC_Time +=
       entry[12]; lof.LngMSULong = entry[31] << 16; lof.LngMSULong +=
       entry[32]; lof2.LngMSULat = entry[34] << 16; lof2.LngMSULat +=
       entry[35]; LongValid = entry[33]; LatValid = entry[36];
       if(LatValid == 0) state = "Valid";
        else state = "Invalid";
       if(LongValid == 0) state2 = "Valid";
        else state2 = "Invalid";
      }
protected:
      short RecDay, RecMonth, RecYear;
      long RecUTC_Time;
      union long_or_float
      {                                      
            float FltMSULong;    
            long LngMSULong;      
      } lof;
      union long_or_float2
      {                  
            float FltMSULat;    
            long LngMSULat;      
      } lof2;
      char* state;
      char* state2;
      short LongValid;
      short LatValid;
};

I think this question is easier to answer than to explain.  Thanks in advance for any help.
0
Comment
Question by:halen
  • 9
  • 6
  • 3
18 Comments
 
LVL 8

Expert Comment

by:trestan
ID: 1168780
You need to declare the COMMOM_DATA instance outside the CWCA constructor so that the operator can access data. Another error is that the overload function should return the stream pointer so that contimeous << can be used.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1168781
>> My objective is to be able to output ( << )  the Common_Data object from the CWCA class by including it in the "friend ostream& operator <<()" function as attempted above.  

It looks to me like you are doing that fine.  In

friend ostream& operator <<(ostream& str, const CWCA& W)
   {return str << "Mission ID: WCA\n" << "MSU WCA ID is: " <<
   W.WCA_ID << endl << "WCA Cmd is: " << W.state << endl <<
   W.Common_Data ;
   }

it looks like the last thing you output is a member called Common_Data  I assume that is the
CCommon class you are saying you want to output   (iit is hard to tell as you didn't post a complete class defintion.)

What's the problem?
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168782
Also pls show what kind of errors occurred in the compiling, linking, and running period. So that we can locate the problem easily.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1168783
I see from testan's response that he is assuming that your code is not compiling (and he's probably right).  Is that the case?  If so it would be good to know!  I'm not sure what he means about returning a stream pointer however.  Your output operators do return references to the stream as is customary, but I don't think that is what he was suggesting.)
0
 

Author Comment

by:halen
ID: 1168784
The compile error I get is:

'CCommon' : no appropriate default constructor available

It points to the CWCA default ctor.  This is the prevalent compile error and I've tried several ways to define the CCommon object including in the "private:" section.  When I try to set up the class this way:

private:
CCommon Common_Data(entry);

It tells me " syntax error : identifier 'entry' ".  Wether the overload will work probably can't be determined until this error is solved.  Back to origional question, I need to be able to create a CCommon object ( with scope into my array) from within the CWCA class and invoke it.  I can declare a CCommon object fine from within my main() function.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1168785
Trestran was right.  To define the CCommon ass a data member of the class, you need to list it in the class declaration like

class CWCA
   {
  // stuff removed.
   private:
   short WCA_ID;
   short WCA_Cmd;
   char* state;
   CCommon Common_Data;
   };

note that there is not attempt to initialize it there, that is I didn't write

CCommon Common_Data(entry);

initilaiztion is done by the constructor.  You don't place it here in the class definiton.
0
 
LVL 22

Expert Comment

by:nietod
ID: 1168786
then inside the constructor you need to initialize the Common_Data member like

CWCA(unsigned short entry[]) :
   Common_Data(entry)
   { WCA_ID = entry[1] >> 8; WCA_Cmd = entry[1] & 255;
   if(WCA_Cmd == 0) state = "Active";
   else state = "Inactive";
   }
0
 
LVL 22

Expert Comment

by:nietod
ID: 1168787
Note that when you had

CWCA(unsigned short entry[])
   {
       CCommon Common_Data(entry);
     // stuff removed.
   }

you were creating and initializing a new CCommon object that was local to the constructor procedure.  As soon as the constructor was done, the object was destroyed.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168788
Thx, nietod.
To question, The error occurs because you did not declare a default constructor for the CCommon class. You have two choices to solve it: one is declare a pointer *Common_Data, then use new to create the instance, the other is to declare a function to initialize the entry data member, then call this function in the CWCA constructor.
BTW, I did not notice the return in the overload function. It is not necessary to write codes in such a consice manner. Since occupying more space does not cost much nowsdays, it is predominant to make the program clear. However, everyone has his own style.
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:halen
ID: 1168789
Thanks trestan for your help.  This is my first posting to the group so I am still getting a feel for the protocol here.  However, nietod really was the one who got the question answered, so if nietod could submit his proposed answer, I'll give him the credit.  The key was to add " : Common_Data(entry) " before the {} in the default ctor.  I verified the correct results.  Thanks again nietod!
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168790
nietod, do you think that I point out the reason for the error at first and you provide an solution before me? Do you think at least we shall share the points?
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168791
halen, I think I point out the error from your abundant codes you posted here before you post the error message. You may think that what you need is an answer. But actually you may know that it is more difficult to figure out the key point of the error. If you did not declare the Common_Data, you will never get it right. I think nietod already gave an biasless judge.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168792
halen, I do not blame you for rejecting my answer. Such things happened often in EE. But what I do suggest you is that you should really unserstand what is point of the question. It is not because the line is put outside the function definition{}, but where to declare the variables (objects). Hope you understand. I think you can ask nietod about this, I feel that he can explain things better than I did.
0
 

Author Comment

by:halen
ID: 1168793
trestan, I had already tried declaring the variables
(objects) outside of the ctor in the private section.  The code I submitted was one of the attempts where I didn't declare the object in the private section.  nietod actually wrote out the correct code where you were telling me to try and use pointers to solve to problem.  I don't think you did all the work and he took all the credit.  In fact, he doesn't seem to concerned about the points so if you want them then submit a proposed answer and you'll get credit.  By the way, I was in EE too.
0
 
LVL 8

Accepted Solution

by:
trestan earned 150 total points
ID: 1168794
It is a question about the scope of a variable(object). When you put it in the class declaration, this variable can be accessed by all the functions (methods) declared in the class (also the friend functions). But if it is declared in a cerntain method (including the constructor), it will be destroyed when the program run out of the method. That is why you can not access the Common_Data in the ">>" function, it does not exist at all. Do you feel better with this explaination?
EE only allow one expert get the points. But actually if you really want to thank another expert. I think you can post another question indicating the points to nietod. You can get 5 free points every day or buy from EE 200 points/&20.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168795
Wait...
I think nietod and I have the same consideration about your problem but have difference solutions for it.
I did not see your comment when I answer it again.
They are the different ways to initialize the object. It has to be "global" to the class no matter how you initialize it.

0
 
LVL 22

Expert Comment

by:nietod
ID: 1168796
>> nietod really was the one who got the question answered,
>> so if nietod could submit his proposed answer, I'll give him
>> the credit
Actually it was Trestan that had the question answered.  I just filled in some additional information that he would have been able to provide as well.  I just filled it in so you didn't have to wait.
0
 
LVL 8

Expert Comment

by:trestan
ID: 1168797
Thank you nietod and halen.
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
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.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

707 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

15 Experts available now in Live!

Get 1:1 Help Now