I have a base abstract class AcctDMA

class AcctDMA { private: char *label; int rating; protected: char* get_label() { return label; } int get_rating() { return rating; } public: AcctDMA(const char * l = "null", int r = 0); AcctDMA(const AcctDMA &rs); virtual ~AcctDMA() = 0; AcctDMA & operator=(const AcctDMA &rs); friend std::ostream & operator<<(std::ostream & os,const AcctDMA & rs); }; 

The class LacksDMA is inherited from this class.

 class lacksDMA : public AcctDMA { private: enum { COL_LEN = 40 }; char color[COL_LEN]; public: lacksDMA(const char *c = "blank", const char * l = "null", int r = 0); lacksDMA(const char * c, const AcctDMA & rs); friend std::ostream & operator<<(std::ostream & os, const lacksDMA & rs); virtual lacksDMA & operator=(const lacksDMA &rs); }; 

Specifically a question about the lacksDMA friendly function

 friend std::ostream & operator<<(std::ostream & os, const lacksDMA & rs); 

here is its implementation

 std::ostream & operator<<(std::ostream & os, const lacksDMA & rs) { os << "color: " << rs.color << std::endl; return os; } 

As expected, the function displays only the color lacksDMA field. I want this function to also display the label and rating fields of the AcctDMA base class. I can not find a single solution to this problem.

I tried this option

 std::ostream & operator<<(std::ostream & os, const lacksDMA & rs) { os << rs.get_label() << std::endl; os << "color: " << rs.color << std::endl; return os; } 

I get two errors when compiling

Error Е1086 - the object contains type qualifiers that are incompatible with the member function "AcctDMA :: get_label (void)"

Error С2662 - char * AcctDMA :: get_label (void): it is not possible to convert the this pointer from "const lacksDMA" to "AcctDMA &"

Also attempted to add the get_bas_label () protected method to the lacksDMA class. The method calls the protected function get_label () and returns its value. Here is the code

 class lacksDMA : public AcctDMA { private: enum { COL_LEN = 40 }; char color[COL_LEN]; protected: char* get_bas_label() { return get_label(); } public: lacksDMA(const char *c = "blank", const char * l = "null", int r = 0); lacksDMA(const char * c, const AcctDMA & rs); friend std::ostream & operator<<(std::ostream & os, const lacksDMA & rs); virtual lacksDMA & operator=(const lacksDMA &rs); }; 

And I try to call it in a friendly function.

 std::ostream & operator<<(std::ostream & os, const lacksDMA & rs) { os << get_bas_label() << std::endl; os << "color: " << rs.color << std::endl; return os; } 

And I get an error - E0020 identifier get_bas_label is not defined

How can I display the fields of the base class?

    2 answers 2

    Your problem is not a friend but const correctness. Try to make these functions public and get the exact same mistake.

    The fact that you use a constant reference const lacksDMA & rs tells the compiler that you are not going to change the state of the object and call non-constant methods. But the get_label and get_rating are just non-constant, which means that they can change the state of the object, hence "Error E1086 - the object contains type qualifiers that are incompatible with the member function".

    Do so

     char* get_label() const { return label; } int get_rating() const { return rating; } 

    and will work.

    Ps. Switch compiler messages to English

      • First, put in order the constant correctness (and read the literature on this topic). Your getter functions must be declared const

          char* get_label() const { return label; } int get_rating() const { return rating; } 

        Now your operator will work in its current form.

      • Secondly, I look at your base class has its own ready operator << . Maybe you need to think about whether you should just call the operator << for the base class from the operator << for the heir, instead of getting into the base class directly

         std::ostream & operator<<(std::ostream & os, const lacksDMA & rs) { os << static_cast<const AcctDMA &>(rs) << std::endl; os << "color: " << rs.color << std::endl; return os; } 
      • Thank you very much for the answers, I struggled with it for several hours. Now I will remember that if an object is constant, then only constant methods can be called. Let me ask you what topic to read in order to understand the line of the code os << static_cast <const AcctDMA &> (rs) << std :: endl; specifically interested in static_cast <const AcctDMA &> (rs) - Nikolay 2