Private inheritance is another way to implement has-a relationship in C + +. With private inheritance, both public and protected members of the base class will be called private members of the derived class. In other words, the base class method will not become part of the public interface of the derived object, but can only be used in the member function of the derived class.
- Public inheritance: the public method of the base class will become the public method of the derived class; The derived class inherits the interface of the base class, which is an is-a relationship.
- Private inheritance: the public method of the base class will become the private method of the derived class; The derived class does not inherit the posted interface, but is a has-a relationship.
Private inheritance provides the same features as inclusion; Get the implementation, but not the interface.
class Student : private std::string, private std::valarray<double> { public: ...// func body }
1. Initialize base class components
project | contain | Private inheritance |
---|---|---|
member object | Provides object members that are displayed and named | An unnamed child object member was provided |
Member list initialization | Use name(str) | Use std::string(str) |
Implementation relationship | has-a | has-a |
//use object names for containment class Student { private: typedef std::valarray<double> ArrayDb; std::string name; ArrayDb score; }; Student(const char* str, const double* pd, int n) : name(str), score(pd, n) {} //use class name for inheritance class Student : private std::string, private std::valarray<double> { public: ...// func body } Student(const char* str, const double* pd, int n) : std::string(str), ArrayDb(pd, n) {}
The second method in the code, class Student, inherits the classes std::string and STD:: valarray < double >, so string and valarray are the base classes of Student class.
2. Method of accessing base class
Private inheritance can only use the method of the base class in the method of the derived class.
Includes using objects to call methods:
double Student::Average() const { if (score.size() > 0) return score.sum() / score.size(); else return 0; }
Private inheritance uses the class name and scope resolution operator to call the method of the base class:
double Student::Average() const { if (ArrayDb::size() > 0) return ArrayDb::sum() / ArrayDb::size(); else return 0; }
You can see from the above two examples:
- When using include, the method will be called with the object name;
- When private inheritance is used, the method is called using the class name and scope resolution operator.
3. Access the base class object itself
By using the scope resolution operator, you can access the methods of the base class. What should you do to access the base class itself?
You can access the base class itself by casting.
The pointer this points to the object used to call the method, * this is the object used to call the method.
const string &Student::Name() const { return (const string &) *this; //Cast object to base class string }
4. Access the base class friend function
First of all, friend functions do not belong to a class, so it is not suitable to call friend functions by explicitly limiting the function name by using the class name. You can call the correct function by explicitly converting to a base class (see below).
friend std::ostream &operator<<(ostream &os, const Student &stu); ostream &operator<<(ostream &os, const Student &stu) { //Display is converted to base class for calling os << "Scores for " << (const string &) stu << ":\n; ... }
In private inheritance, a derived class reference or pointer without display type conversion cannot be assigned to a reference or pointer of a base class.
5 choice of inclusion and private inheritance
Although both methods can be used, both establish has-a relationship and can do the same work. But most C + + programmers tend to use include.
contain
- The inclusion is simple. The class declaration contains the display named object representing the included class, which can be referenced by name. package
- It can include multiple sub objects of the same kind (for example, three independent string s can be declared).
- Cannot access for protected members.
- Virtual functions cannot be redefined.
Private inheritance
- Inheritance makes the relationship more abstract. At the same time, when inheriting from multiple base classes, it may cause a series of problems that need special treatment.
- Inheritance can only use one such object.
- Inheritance has more features. When it contains protected members, derived classes can be used.
- Virtual functions can be redefined.
Generally, inclusion should be used to establish has-a relationship; If the new class needs to access the protected members of the original class, or needs to redefine the virtual function, private inheritance should be used.