简体   繁体   中英

cannot access private members in friend ostream

I tried to make friend ostream function. The compiler say i cannot access private member of the class, even though i declared it as friend . I read a similar question and it say the problem is with the namespcaes.(the question: C++ friend function can't access private members )

My Code is below:

header:

#include <iostream>
#include <string>
//using namespace std;

namespace biumath
{
#ifndef BIUMATH_H
#define BIUMATH_H
class Assignment
{
private:
    int **m_varArray;
    int m_rowsOfVarArray;
public:
     Assignment(); //1
     Assignment(char symbol, double value); //2
     bool containsValueFor(char symbol) const; //3
     double valueOf(char symbol) const; //4
     void add(char symbol, double val); //5
     friend std::ostream& operator<< (std::ostream& out, 
     const Assignment& assignment);
};
}
#endif

cpp:

#include <iostream>
#include "biumath.h"
using namespace biumath;
using std::cout;
using std::endl;

ostream& operator<< (ostream& out, 
     const Assignment& assignment){
        out<<assignment.m_rowsOfVarArray<<std::endl;
        //return the stream. cout print the stream result.
        return out;
}

or better yet, avoid all unnecessary friendships by deferring to a public utility method (this also has benefits when your Assignment is a polymorphic base class):

in header file:

namespace biumath
{
    class Assignment
    {
    private:
        int **m_varArray;
        int m_rowsOfVarArray;
    public:
        Assignment(); //1
        Assignment(char symbol, double value); //2
        bool containsValueFor(char symbol) const; //3
        double valueOf(char symbol) const; //4
        void add(char symbol, double val); //5
        void write(std::ostream& os) const; // <=== public helper
    };

    // free function overload which defers to helper.
    // NOTE: it's in the biumath namespace so ADL will find it

    inline std::ostream& operator<< (std::ostream& out,
                                       const Assignment& assignment){
        assignment.write(out);
        return out;
    }
}

in CPP file:

namespace biumath {

    void Assignment::write(std::ostream& os) const {
        os << m_rowsOfVarArray << std::endl;
    }
}

You may define the operator in the enclosing namespace (in your case in the global namespace) but you have to use the qualified name.

Thus define the operator like

ostream& biumath::operator<< (ostream& out, 
     const Assignment& assignment){
        out<<assignment.m_rowsOfVarArray<<std::endl;
        //return the stream. cout print the stream result.
        return out;
}

Only you also have at first to declare the operator in the same namespace where the class is defined.

If you want that the operator would be declared in the global namespace then you can do it the following way

namespace biumath
{
class Assignment;
}

std::ostream& operator<< ( std::ostream &, 
                           const biumath::Assignment & );


namespace biumath
{
class Assignment
{
     //...
     friend std::ostream& ::operator<< (std::ostream& out, 
                                        const Assignment& assignment);
};
}

You've befriended an operator in your biumath namespace, but you don't define that; instead you define a separate operator in the global namespace.

Re-open the namespace in the source file, and put the definition inside it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM