After defining friend function, can't access the private variable of a class

I've written a simple employee management project. I am facing problem when I am trying to assign values into the private variables of a class though I defined the operator overloading as friend function.

Here is my code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include<iostream>
#include<string>
#include<vector>
#include<fstream>

using namespace std;

class Person
{
    string pName;
    char pSex;
    int pAge;
    string pMob;
    string pAddress;

public:
    Person(){}
    Person(string &pn, char &ps, int &pa, string &pm, string &pad):
        pName(pn),pAge(pa),pMob(pm),pAddress(pad),pSex(ps){}

    string getName(){return pName;}
    int getAge(){return pAge;}
    string getMob(){return pMob;}
    string getAddress(){return pAddress;}
    char getSex(){return pSex;}
};

class Employee:public Person
{
    string eID;
    string eJDate;
    string eRank;
    double eSalary;

public:
    Employee(){}
    Employee(string &pn, char &ps, int &pa, string &pm, string &pad, string &eid, string &ejd, string &er,  double &es):
        Person(pn,ps,pa,pm,pad),eID(eid),eJDate(ejd),eRank(er),eSalary(es){}

    string getID(){return eID;}
    string getJDate(){return eJDate;}
    string getRank(){return eRank;}
    double getSalary(){return eSalary;}

    friend ostream& operator<<(ostream& os, Employee& ob);
    friend istream& operator>>(istream& inf, Employee& ob);
};

ostream& operator<<(ostream& os, Employee& ob)
{
    os<<ob.getName()<<endl;
    os<<ob.getSex()<<endl;
    os<<ob.getAge()<<endl;
    os<<ob.getMob()<<endl;
    os<<ob.getAddress()<<endl;
    os<<ob.getID()<<endl;
    os<<ob.getJDate()<<endl;
    os<<ob.getRank()<<endl;
    os<<ob.getSalary()<<endl;

    return os;
}

istream& operator>>(istream& inf, Employee& ob)
{
    inf>>ob.pName;
    inf>>ob.pSex;
    inf>>ob.pAge;
    inf>>ob.pMob;
    inf>>ob.pAddress;
    inf>>ob.eID;
    inf>>ob.eJDate;
    inf>>ob.eRank;
    inf>>ob.eSalary;

    return inf;
}

int main()
{
    cout<<"\t\t\t\tEnter your choice\n";
    cout<<"\t\t\t\t-----------------\n";

    cout<<"1: Enter an employee data."<<endl;
    cout<<"2: View all the employee data."<<endl;
    cout<<"Enter choice: ";

    int choice;
    cin>>choice;

    if(choice==1)
    {
        string name,mob,address,id,jdate,rank;
        int age;
        char sex;
        double salary;

        ofstream out;
        out.open("DB.txt",ios_base::app);

        cout<<"Enter Name : ";
        cin>>name;
        cout<<"Enter Sex (M/F): ";
        cin>>sex;
        cout<<"Enter Age : ";
        cin>>age;
        cout<<"Enter Mobile No : ";
        cin>>mob;
        cout<<"Enter Address : ";
        getline(cin,address);
        cout<<"Enter ID : ";
        cin>>id;
        cout<<"Enter Join Date (dd-mm-yyyy): ";
        cin>>jdate;
        cout<<"Enter Position : ";
        cin>>rank;
        cout<<"Enter Salary : ";
        cin>>salary;

        Employee ob(name, sex, age, mob, address, id, jdate, rank, salary);

        out<<ob;
    }
    else if(choice==2)
    {
        ifstream inf("DB.txt");
        vector<Employee>ve;
        Employee ob;
        while(inf>>ob)
        {
            ve.push_back(ob);
        }

        for(int i=0; i<ve.size(); i++)
        {
            cout<<"\nEmployee No - "<<i<<endl;
            cout<<"Employee Name: "<<ve[i].getName()<<endl;
            cout<<"Sex: "<<ve[i].getSex()<<endl;
            cout<<"Age: "<<ve[i].getAge()<<endl;
            cout<<"Mobile: "<<ve[i].getMob()<<endl;
            cout<<"Address: "<<ve[i].getAddress()<<endl;
            cout<<"ID: "<<ve[i].getID()<<endl;
            cout<<"Joining Date: "<<ve[i].getJDate()<<endl;
            cout<<"Rank: "<<ve[i].getRank()<<endl;
            cout<<"Salary: "<<ve[i].getSalary()<<endl;
        }
    }
    return 0;
}


It is giving the following erros-

1
2
3
4
5
6
7
8
9
10
11
7|error: ‘std::string Person::pName’ is private|
63|error: within this context|
8|error: ‘char Person::pSex’ is private|
64|error: within this context|
9|error: ‘int Person::pAge’ is private|
65|error: within this context|
10|error: ‘std::string Person::pMob’ is private|
66|error: within this context|
11|error: ‘std::string Person::pAddress’ is private|
67|error: within this context|
||=== Build failed: 10 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|


How do I fix this? Please give specific solution.
Last edited on
Class Employee indeed gave access to its private variables to operator>>. But it cannot give access to variables which does not belong to it. pName belong to the Person class, not Employee.
But Employee inherit Person class. I can access to Person class data using operator<< so why not operator>> ? Moreover I defined operator>> as friend function.

So What should I do to Fix it? @MiiNiiPaa
Last edited on
I can access to Person class data using operator<<
You do not access private fields using output operator. You use public interface of Person.

But Employee inherit Person class.
But Employee still cannot make decision for Person part. Think about it this way: you can enter your parents home. You can keys to your home to your friends. But you cannot just give your friend keys to your parents home without their permission or knowledge.
https://isocpp.org/wiki/faq/friends#friendship-not-inherited-transitive

Moreover I defined operator>> as friend function.
And it is a frien of Employee class. You can access fields eID eJDate, etc just fine with them.

So What should I do to Fix it?
One solution is to define separate operator for Person class and call it in derived class operator

1
2
3
4
5
6
7
8
9
10
11
12
//Make it a friend of Person and implement filling of Person fields.
istream& operator>>(istream& inf, Person& ob); 

istream& operator>>(istream& inf, Employee& ob)
{
    inf >> static_cast<Person&>(ob); //Fill Person parts
    inf>>ob.eID;
    inf>>ob.eJDate;
    inf>>ob.eRank;
    inf>>ob.eSalary;
    return inf;
}
Topic archived. No new replies allowed.