I have overloaded the << & >> operators and I though I could access private data members of the class if I declared the functions friends of the class. I am getting four errors in the two overloaded functions that are trying to access the private members firstName and lastName. Anyone have any ideas as to what I am doing wrong?

#ifndef H_personType
#define H_personType

#include <string>
 
using namespace std;

class personType
{
    friend ostream& operator<< (ostream&, const personType &);
    friend istream& operator>> (istream&, personType &);
public:
    void print() const;
       //Function to output the first name and last name
       //in the form firstName lastName.
  
    void setName(string first, string last);
       //Function to set firstName and lastName according 
       //to the parameters.
       //Postcondition: firstName = first; lastName = last

    string getFirstName() const;
       //Function to return the first name.
       //Postcondition: The value of the firstName is returned.

    string getLastName() const;
       //Function to return the last name.
       //Postcondition: The value of the lastName is returned.

    personType(string first = "", string last = "");
       //constructor
       //Sets firstName and lastName according to the parameters.
       //The default values of the parameters are empty strings.
       //Postcondition: firstName = first; lastName = last  

 private:
    string firstName; //variable to store the first name
    string lastName;  //variable to store the last name
};

#endif
#include <iostream>
#include <string>
#include "personType.h"

using namespace std;

ostream& operator<< (ostream& osObject, const personType& name)
{
    osObject << name.firstName << name.lastName;

    return osObject;
}

istream& operator>> (istream& isObject, personType& name)
{
    isObject >> name.firstName >> name.lastName;

    return isObject;
}

void personType::print() const
{
    cout << firstName << " " << lastName << endl;
}

void personType::setName(string first, string last)
{
    firstName = first;
    lastName = last;
}

string personType::getFirstName() const
{
    return firstName;
}

string personType::getLastName() const
{
    return lastName;
}

    //constructor
personType::personType(string first, string last) 
{ 
    firstName = first;
    lastName = last;
}

The program looks good. Mind posting the line numbers and the exact errors you are getting.

persontype.cpp(10) : error C2248: 'personType::firstName' : cannot access private member declared in class 'personType'
persontype.h(37) : see declaration of 'personType::firstName'
persontype.h(11) : see declaration of 'personType'
persontype.cpp(10) : error C2248: 'personType::lastName' : cannot access private member declared in class 'personType'
persontype.h(38) : see declaration of 'personType::lastName'
persontype.h(11) : see declaration of 'personType'
persontype.cpp(17) : error C2248: 'personType::firstName' : cannot access private member declared in class 'personType'
persontype.h(37) : see declaration of 'personType::firstName'
persontype.h(11) : see declaration of 'personType'
persontype.cpp(17) : error C2248: 'personType::lastName' : cannot access private member declared in class 'personType'
persontype.h(38) : see declaration of 'personType::lastName'
persontype.h(11) : see declaration of 'personType'

Member Avatar for iamthwee

> personType(string first = "", string last = "");

That line strikes me as odd.

default constructor which creates two empty strings

Member Avatar for iamthwee

default constructor which creates two empty strings

But is it right?

Thats how my textbook coded this particular constructor. The program was working fine until I added the two overloaded operators. I am only having the problem with those two funcitons. I thought friend functions could directly access the private member variables!

Member Avatar for iamthwee

Thats how my textbook coded this particular constructor. The program was working fine until I added the two overloaded operators. I am only having the problem with those two funcitons. I thought friend functions could directly access the private member variables!

hmm, no compiler here to test... I wuda personally done:

personType(string first, string last)
{
first = "";
last = "";
}
Again no idea if that's legal, no compiler to test it with.


The only other thing I can think of is you may be missing an arbitary var?

friend ostream& operator<< (ostream &var, personType &var);
friend istream& operator>> (istream &var, personType &var);

And possibly the const keywords might be causing problems. I'd chop them out.

http://www.codersource.net/cpp_stream_operators.html

And are you using the setName(string first, string last) function to initialise it?

hmm, no compiler here to test... I wuda personally done:

personType(string first, string last)
{
first = "";
last = "";
}
Again no idea if that's legal, no compiler to test it with.

Your code is completely different from his and definitely not what he's trying to do. Default paramater values allow for the parameter to be omitted when the function is called. His implementation would allow for someone to do:

personType p();
personType p("");
personType p("","");

and the three would be identical and would all go through the same constructor. Your code, on the other hand, would change the parameter values to "" inside the function body. ;)

The program looks good. Mind posting the line numbers and the exact errors you are getting.

~s.o.s~ is right, at first glance it doesn't seem like there's anything wrong with the code. I just tried compiling it, and it compiles without any errors on gcc. What compiler are you using?

Personally, I'd do your constructor like this:

personType(string first = "", string last = "") 
      : firstName(first), lastName(last);

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6

I use Visual studio 2005.

I use Visual studio 2005.

Perhaps there's a setting you need to change or something?

Anyway, I don't have a Windows box I can try your program with, so I guess you'll have to wait until someone else comes on who does have one.

bah, I guess I'll dust off the ol' VS2005... :p

I took the code from the first post, used a basic main to run it (making a personType and calling print()), and it worked fine.

Well I dont understand that I have the exact same code in VS 05 and I get the dern errors

Another gentleman said he input my code into .net 2003 and it compiled fine, he then converted it to VS 2005 and still compiled ok. He also stated that there were no significant changes in the conversion. I am still seeking input on this problem, so if anyone can help I would greatly appreciate it.

out of curiosity, have you tried making the putting the friend statements after the public modifier? I don't know whether or not that might change anything (I didn't need to...)

When overloading the insertion and extraction operators they must be nonmember functions because cout and cin are not objects of the class

I have the sample code, but didn't work out.

I have the sample code, but didn't work out.

Like:

  • The compiler you were using
  • The version number (or year) of the compiler
  • The errors you got

The code won't compile by itself, because it is missing a main() function. If you want to compile it yourself, you're going to have to make one like Infarction did.

Hi !,
I'm using VS Enterprise edition 6.0.
Unfortunately the code you posted in the first post works without any problems. :)
Only guess I have is that the compiler does not think the operator overload function you've declared as friend is same as the one you've defined.

Try giveing explicite scope resolution. E.g. push the function definitions in a namespace say my_name_space and change the friendship declaration to include explicite scope resolution.

//CLASS DECLARATION
class personType
{
     friend ostream& my_name_space::operator<< (ostream&, const personType &);
     friend istream& my_name_space::operator>> (istream&, personType &);
//..... rest of the class decl.
};

//FUNCTION DEFINITION
namespace my_name_space {
ostream& operator<< (ostream& osObject, const personType& name)
{/*impl*/}

istream& operator>> (istream& isObject, personType& name)
{/*impl*/}
}//namespace my_name_space

------------------------
Just to ensure code I posted works I tried it out and here is what I got:
d:\my\tech\lssd\test\test.cpp(9) : error C2653: 'my_name_space' : is not a class or namespace name

From this error it seems like the compiler is looking for at least a fwd decl of these "friend functions", which when added made the code compile. I added this before class declaration starts.

class personType ;
namespace my_name_space { 
    ostream& operator<< (ostream&, const personType &);
    istream& operator>> (istream&, personType &);
}

But interesting part is why didn't the compiler ask for fwd decl in your original code? (my guess is it's needed for classes/namespaces but not for function)
-------------------------

Member Avatar for iamthwee

Hey I just compiled your code and it worked in devshed. So there must be something wrong with VS 2005, or you ain't compiling and linking it properly or missing a header file or -- who knows.

If only I compiled it first then I wouldn't have lead you on that wild goose chase. Oh well.

:lol:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.