Access specifiers:
Private: accessible by only the class it is declared in
Public: accessible by everyone, including derived classes
Protected: accessible by only the class it is declared in and derived classes, not commonly used and is considered an advanced topic.
- Some programmers argue that protected data fields are usually a bad idea because the derived classes may corrupt the base-class variables.
- An alternative is to leave the data fields private and provide derived classes with protected accessor methods
E.g. Notice the const modifier to ensure that it's a read-only method
class Char {
public:
virtual void draw() const;
protected:
double value_at(int index) const;
private:
vector<double> data;
};
Access specifiers in inheritance:
Public: the most commonly used inheritance access specifier, grants derived class with public and protected access members and methods from the base class.
E.g.
class A {
private:
int pr_i;
public:
int pu_i;
protected:
int pt_i;
};
class B: public A {
};
Class B has access to pu_i and pt_i but not pr_i.
Private: Rarely used, this the default inheritance specifier if not provided. The inherited methods, members of the base class will be marked with "private" access specifier in the derived class. This means that if another class derives the derived class it will not have any access to the base class's members nor methods.
E.g. default inheritance specifier. Assume class A has definition as above
These two are equivalent:
class B: private A {};
class B: A {};
B has access to pu_i and pt_i but not pr_i, which is expected. Now if we have another class that derives B:
class C: public B {};
C doesn't have access to any of A's members or methods, even if we put "public" in front of B
Private inheritance above is equivalent to this:
class B {
private:
int pr_i;
int pu_i;
int pt_i;
};
class C: public B {
};
We can undersstand now why C doesn't have access to any of pr_i, pu_i, pt_i even if we put "public" in front of B.
Protected:
Advanced topic.
Friends:
- Friends of an object can either be a function or a class
- The friend function or class has access to all private features of the class.
- The function declaration or class name must be explicitly named within the class definition of the one sharing their members, friend declaration placement is same anywhere, no matter under private/protected or public accessor modifiers friends will access to everything
- Friends are not inherited
- If A is a friend of B does not imply B is a friend of A
E.g.
class A {
private:
int m_x;
int m_y;
friend class B; // class B has access to private members of A
friend int calculateFoo(int a, int b); // the function calculateFoo has access to private members of A
};
Common uses:
- output stream operator that requires access to the inner state of an object
E.g.
class Employee {
public:
Employee(string employee_name, double initial_salary);
private:
string name;
double salary;
friend ostream& operator<<(ostream& out, const Employee& e);
};
ostream& operator<<(ostream& out, const Employee& e) {
out << "Employee: " << e.name;
return out;
}