Search code examples
operator-overloadingmultiple-inheritancefriend-function

Why can't I access the private variable of a class after defining a friend function?


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:

#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-

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)) ===|

Here I can access and assign value to the private variables of Employee class, but can't get access to the private variables of Person class.

Friend function doesn't work here?

How do I code to solve it? How do I load data from file into an object of Employee class?


Solution

  • When you declare a member private in a class it's private for the class itself, even to its children. So pName in your example is inaccessible from Employee's child class. If you declare it protected, then the child class can access it (and modify it)

    In order to change it in the child class while still keeping the member private, you need to provide accessor (get/set methods) in the parent class. 'setPName' accessor can be public, or protected if you want to limit modification to the Employee class.