Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 383
  • Last Modified:

Inheritance and overloading with a twist

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
halen
Asked:
halen
  • 9
  • 6
  • 3
1 Solution
 
trestanCommented:
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
 
nietodCommented:
>> 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
 
trestanCommented:
Also pls show what kind of errors occurred in the compiling, linking, and running period. So that we can locate the problem easily.
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
nietodCommented:
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
 
halenAuthor Commented:
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
 
nietodCommented:
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
 
nietodCommented:
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
 
nietodCommented:
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
 
trestanCommented:
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
 
halenAuthor Commented:
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
 
trestanCommented:
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
 
trestanCommented:
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
 
trestanCommented:
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
 
halenAuthor Commented:
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
 
trestanCommented:
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
 
trestanCommented:
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
 
nietodCommented:
>> 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
 
trestanCommented:
Thank you nietod and halen.
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 6
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now