Sign in to follow this  

Friend isn't friendly

This topic is 3311 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have some code where I am overloading the insertion and extraction operators. Even though I have declared both overloaded operators to be friends of my class I am getting an exception saying that the overloaded operator doesn't have access to private members of my class. Start.h
[source lang=cpp]
#ifndef IGES_SECTION_START_H_
#define IGES_SECTION_START_H_

#include <iosfwd>
#include <string>

namespace IGES
{
	namespace Section
	{
		class Start
		{
		public:
			friend std::ostream & operator<<(std::ostream & stream, Start const & start);
			friend std::istream & operator>>(std::istream & stream, Start const & start);
		protected:
		private:
			std::string data;
		};
	};
};

std::ostream & operator<<(std::ostream & stream, IGES::Section::Start const & start);
std::istream & operator>>(std::istream & stream, IGES::Section::Start const & start);

#endif


Start.cpp
[source lang=cpp]
typedef std::map<IGES::Datatype::Integer, std::string> map_type;

std::istream & operator>>(std::istream & stream, IGES::Section::Start const & start)
{
	std::string line;
	map_type lines;
	do
	{
		std::ios_base::streampos startOfLine = stream.tellg();
		std::getline(stream, line);
		if(line[72] == 'S')
		{
			if(line.size() != 80)
			{
				throw new std::invalid_argument("start lines must be 80 charaters long");
			}
			IGES::Datatype::Integer lineNumber = boost::lexical_cast<IGES::Datatype::Integer>(line.c_str() + 72);
			lines.insert(std::make_pair(lineNumber, std::string(line.begin(), line.begin() + 72)));
		}
		else
		{
			stream.seekg(startOfLine);
		}
	}while(line[72] == 'S');
	for(map_type::const_iterator i = lines.begin(); i != lines.end(); ++i)
	{
		start.data.append(i->second);
	}
	return stream;
}

The error is on the line that says: start.data.append(i->second); It says that I can't access private member data of class Start. Am I misusing friend? I very rarely have need of it, so I'm not nearly as familiar with its intricacies as other parts of C++.

Share this post


Link to post
Share on other sites
The problem is that your friend declarations have friended operator<< and operator>> inside the IGES::Section namespace and your definitions live in the root namespace. The easiest fix would be to put the definitions in the IGES::Section namespace.

Share this post


Link to post
Share on other sites
Would that solution still allow me to something like:
[source lang=cpp]
#include <Start.h>
#include <iostream>
int main()
{
Start s;
std::cin >> s;
return 0;
}

Share this post


Link to post
Share on other sites
Sign in to follow this