ron252
ron252

Reputation: 21

overloaded extraction operator won't friend in C++

I'm working on extraction and insertion overloads. And I can't access the private variables while using friend.

This is my code based a standard tutorials and what my teacher gave me to work with

Main.cpp

#include <iostream>
#include "Obj.h"

using namespace std;
using namespace N;

Obj a;

int main() {
  cout << a;
}

Obj.cpp

#include "Obj.h"
#include <iostream>

using namespace std;
using namespace N;

ostream &operator<<(ostream &output, const Obj &a) {
    output << a.h;
    return output;
}

Obj.h

#ifndef OBJ_H
#define OBJ_H

#include <iostream>

using namespace std;

namespace N {
    class Obj {
        private:
        string h; 

        public:

        //constructors
        Obj() {
            h = "default";
        }

        //overloads
        friend ostream &operator<<(ostream &output, const Obj &a);
    };
}

#endif

I started from a header file setup and broke it down to this while getting the same error code. In particular I keep getting this result.

Obj.cpp:9:15: error: 'h' is a private member of 'N::Obj'
  output << a.h;
              ^
./Obj.h:12:14: note: declared private here
      string h; 

Upvotes: 0

Views: 102

Answers (2)

Yksisarvinen
Yksisarvinen

Reputation: 22284

The issue is with the fact that you declare your friend function in namespace N, but you define it in the global namespace. using namespace N; does not put any definition in the namespace, it only lets compiler guess that it should be from that namespace if it has other clues for that (e.g. you are defining a method of a class). Here, there's nothing to suggest that this operator should not be in the global namespace, so it is there.

The solution is use namespaces correctly:

#include "Obj.h"
#include <iostream>

using namespace std;
namespace N {

ostream & operator << (ostream &output, const Obj &a){
  output << a.h;
  return output;
}

}

And while we're at it, using namespace std; is not a good practice either.

Upvotes: 2

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275585

Put the body of << in the class declaration.

It can be as short as a.printTo(output); return output;.

Then write printTo.

The rules for introducing a name as a friend declaration are sometimes tricky. I'm guessing your real code, Obj is a template, or some minor chsnge messes up the match, etc. The above pattern sidesteps those issues.

Upvotes: 0

Related Questions