l Base-class constructors,destructors, and assignment operators are not inherited by derivedclasses. Derived class constructors and assignment operators, however,can call base-class constructors and assignment operators.Friendfunctions are not inherited// Constructor for Circle calls constructor for Point // with a member initializer then initializes radius. Circle::Circle( int a, int b, double r ) : Point( a, b ) // call base-class constructor { setRadius( r ); }
<div><span style="color: rgb(153, 102, 0); ">l</span><u>If the base-classconstructor is not explicitly called, the base-class default constructor isimplicitly called. </u></div><div><span style="color: rgb(153, 102, 0); ">l</span>Destructors are called in reverse order of constructors.</div>
Types of Inheritance
There are five different inheritances supported in C++:
- (1) Simple / Single
- (2) Multilevel
- (3) Hierarchical
- (4) Multiple
- (5) Hybrid
Accessibility modes and Inheritance
We can use the following chart for seeing the accessibility of the members in the Base class (first class) and derived class (second class).
Private member in base class, when we are in derived class, we can access them through the function we inherit from base class. We can't call them directly in new created derived class member function.
Virtual Inheritance:
class storable //this is the our base class inherited by transmitter and receiver classes { public: storable(const char*); virtual void read(); virtual void write(); virtual ~storable(); private: .... }
class transmitter: public virtual storable
{ public: void read(); ... } class receiver: public virtual storable { public: void read(); ... }
class radio: public transmitter, public receiver { public: void read(); .... }When we use virtual inheritance, we are guaranteed to get only a single instance of the common base class. In other words, the radio class will have only a single instance of the storable class, shared by both the transmitter and receiver classes. By having a single instance ofstorable, we've resolved the compiler's immediate issue, the ambiguity, and the code will compile fine.
The instanciation of virtual base class storable is the responsibility of the bottom class radio. One thing to be aware of is that if either transmitter or receiver attempted to invoke the storable constructor in their initialization lists, that call will be completely skipped when constructing a radio object!
(1) classes derived from virtual bases that require initialization must be aware of their virtual bases, no matter how far distant the bases are, and (2) when a new derived class is added to the hierarchy, it must assume initialization responsibilities for its virtual bases (both direct and indirect).
Delegating to a sister class
A powerful technique that arises from using virtual inheritance is to delegate a method from a class in another class by using a common abstract base class. This is also called cross delegation. Let's assume we have a similar scenario like in the diamond example, with small changes. Suppose the write() method in transmitter class needs to access the read() method from receiver for the radio to work (this is kind of a weird behavior, but let's take it for the sake of illustration) :class storable { public: storable(const char*); virtual void read()=0; //this becomes pure virtual making storable an abstract virtual void write(); //class virtual ~storable(); private: .... } class transmitter: public virtual storable { public: void write() { read(); .... } } class receiver: public virtual storable { public: void read(); } class radio: public transmitter, public receiver { public: ... } int main() { radio *rad = new radio(); receiver *r1 = rad; transmitter *r2 =rad; rad->write(); r1->write(); r2->write(); return 1; }Because of virtual inheritance, when the write() function from the transmitter class is called, the method read() from the receiver class gets called (as you may have noticed, the transmitter class doesn't have a read() function). In the above hierarchy we can instantiate only the radio class because transmitter and receiver are abstract due to virtual inheritance.
Friend function&Class
A C++ friend functions are special functions which can access the private members of a class. They are considered to be a loophole in the Object Oriented Programming concepts, but logical use of them can make them useful in certain cases. For instance: when it is not possible to implement some function, without making private members accessible in them. This situation arises mostly in case of operator overloading.
#include <iostream> using namespace std; //Must be known to TWO //before declaration of ONE. class ONE; class TWO { public: void print(ONE& x); }; class ONE { int a, b; friend void TWO::print(ONE& x); public: ONE() : a(1), b(2) { } }; void TWO::print(ONE& x) { cout << "a is " << x.a << endl; cout << "b is " << x.b << endl; } int main() { ONE xobj; TWO yobj; yobj.print(xobj); }
Friend functions have the following properties:
- 1) Friend of the class can be member of some other class.
- 2) Friend of one class can be friend of another class or all the classes in one program, such a friend is known as GLOBAL FRIEND.
- 3) Friend can access the private or protected members of the class in which they are declared to be friend, but they can use the members for a specific object.
- 4) Friends are non-members hence do not get “this” pointer.
- 5) Friends, can be friend of more than one class, hence they can be used for message passing between the classes.
- 6) Friend can be declared anywhere (in public, protected or private section) in the class.
- Another property of friendships is that they are not transitive: The friend of a friend is not considered to be a friend unless explicitly specified.
-
#include <iostream> using namespace std; class MyClass { // Declare a friend class friend class SecondClass; public: MyClass() : Secret(0){} void printMember() { cout << Secret << endl; } private: int Secret; }; class SecondClass { public: void change( MyClass& yourclass, int x ) { yourclass.Secret = x; } }; void main() { MyClass my_class; SecondClass sec_class; my_class.printMember(); sec_class.change( my_class, 5 ); my_class.printMember(); }