Meis
Meis

Reputation: 13

Multiple Inheritance need to acces to private variable

I don't know how access to private variable Multiple Inheritance.

In this code I create person class

class person {
    char name[20]; char lname[20];
public:
    person() {}
    person(char*n, char*ln);
    virtual void print(ostream&o);
};
person::person(char*n, char*ln)
{
    strcpy_s(name, 20, n);
    strcpy_s(lname, 20, ln);
}

void person::print(ostream&o)
{
    o << "name: " << name << "  " << "last name: " << lname << endl;
}
ostream& operator<<(ostream&o, person&p)
{
    p.print(o);
    return o;
}

by Inheritance I create student and teacher class

class student : public virtual person
{friend class ststudent;

    long str;
public:

    student(char*n, char*ln, long s);
    void print(ostream&o);
};

student::student(char*n, char*ln, long s) :person(n, ln), str(s) {}

void student::print(ostream&o)
{
    person::print(o);
    o << "st_num :  " << str << endl;
}




class teacher : public virtual person
{
    long salary;

public:

    teacher(char*n, char*ln, long s);
    virtual void print(ostream&o);
};

teacher::teacher(char*n, char*ln, long sal) :person(n, ln), salary(sal) {}

void teacher::print(ostream&o)
{
    person::print(o);
    o << "salary :  " << salary << endl;
}

and in last class I use from Multiple Inheritance to create teacher assistant class but I don't know how to print the str and salary

class stteacher :public teacher, public student
{

public:
    stteacher(char*n, char*ln, long st, long sa)
        :student(0, 0, st), teacher(0, 0, sa), person(n, ln) {}
    virtual void print(ostream&o);
};

void stteacher::print(ostream& o)
{
    person::print(o);
    o << str << salary;

}

I don't know how to do it. I can create two variables in stteacher class or change str and salary from private to public variable but I think I should do this with Multiple Inheritance. Help me please.

Upvotes: 0

Views: 254

Answers (3)

Juan
Juan

Reputation: 111

Classes by default are private, which means that anything before specifying access modifiers is private.

Private methods / local variables can only be accessed by the class that defined them and it's friend classes. In your case, to define a friend class you should first tell to student and teacher what stteacher is.

C++ reads your code from top to bottom, so if you want to use a variable/class/macro/whatever, you should declare it above it's use.

In code, this would look something like:

extern class stteacher; //You tell C++ that 'stteacher' is a class

class person {};

class student : public virtual person {
    long str;
    friend class stteacher; //You make stteacher a friend of student
public:
    student(long str) : str(str) {}
};

class teacher : public virtual person {
    long salary;
    friend class stteacher; //You make stteacher a friend of teacher
public:
    teacher(long salary) : salary(salary) {}
};

class stteacher : public student, public teacher {
public:
    stteacher(long str, long salary) : student(str), teacher(salary) {}
    void print() {
        std::cout << "Salary: " << salary << "\nStr: " << str << std::endl;
    }
}

int main() {
    long str = 10, salary = 100;
    stteacher(str, salary).print();
    return 0;
}

Salary: 100

Str: 10

Eventhough this works, I suggest it would be best to use a more apropiate access modifier, such as protected.

protected stuff can be accessed by the class which defines it, it's friend classes AND classes which inherits it.

Using protected access modifiers, the above code would look like: extern class stteacher; //You tell C++ that 'stteacher' is a class

class person {};

class student : public virtual person {
protected: //Can be accessed by it's childs
    long str;
public:
    student(long str) : str(str) {}
};

class teacher : public virtual person {
protected: //Can be accessed by it's childs
    long salary;
public:
    teacher(long salary) : salary(salary) {}
};

class stteacher : public student, public teacher {
public:
    stteacher(long str, long salary) : student(str), teacher(salary) {}
    void print() {
        std::cout << "Salary: " << salary << "\nStr: " << str << std::endl;
    }
}

int main() {
    long str = 10, salary = 100;
    stteacher(str, salary).print();
    return 0;
}

Salary: 100

Str: 10

Upvotes: 0

Chris Uzdavinis
Chris Uzdavinis

Reputation: 6131

Private data in a class cannot be accessed by any non-member, non-friend code. Period. Whether you use inheritance (or not) is irrelevant.

Thus, the only way for a different class to access that data is to:

  • Provide accessor function(s) so that callers can fetch the data. (If public, anyone can call it, but if it's a protected function then only derived classes gain access to it.)

  • Alternately, make the class(es) that need access a friend of the class. Friendship is something c++ programmers generally discourage, however, so only do so as a true last resort.

  • Change the access to the data to be public. (Very discouraged, as this defeats encapsulation entirely.)

Upvotes: 1

dmedine
dmedine

Reputation: 1555

A pattern for accessing private variables is to make a public function that returns that variable:

class teacher : public virtual person
{
    long salary;

public:

    teacher(char*n, char*ln, long s);
    virtual void print(ostream&o);
    long get_salary(void){return salary;}
};

Then the implentation for stteacher::print would be:

void stteacher::print(ostream& o)
{
    person::print(o);
    o << get_salary();

}

or something like this.

Upvotes: 0

Related Questions