asdas asda
asdas asda

Reputation: 1

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;
}

Upvotes: 0

Views: 2180

Answers (3)

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

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);
};
}

Upvotes: 1

Richard Hodges
Richard Hodges

Reputation: 69882

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;
    }
}

Upvotes: 5

Mike Seymour
Mike Seymour

Reputation: 254461

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.

Upvotes: 0

Related Questions