"C + + Primer Plus" 14.2 Private inheritance Learning notes

Source: Internet
Author: User
Tags function definition

C + + (in addition to member variables) has another way to implement has-a relationships-private inheritance.
With private inheritance, both the public and the protected members of the base class become private members of the derived class.
(If you use protection inheritance, the public and protected members of the base class are referred to as protected members of the derived class.) )
This means that the base class methods will not be called part of the common interface of the derived class object, but they can be used in the member functions of the derived class.
14.2.1 Student Class Example (new version)
The student class should derive from two classes, so the declaration will list these two classes:
Class Student:private std::string, Private std::valarray<double>
{
Public
...
};
Inheritance using multiple base classes is called multiple inheritance (multiple Inheritance,mi).
The new student class does not require private data, because two base classes already provide all the data members that are required. The Include version (in section 14.1) provides two explicitly named object members, while private inheritance provides two unnamed child object members. This is the first major difference between the two methods.
1. Initializing the base class component
Implicitly inheriting a component instead of a member object will affect the code's writing, since it is no longer possible to use name and scores to describe the object, but must use techniques for public inheritance. For example, for constructors, include constructors that will use such a constructor:
Student (cosnt char * str, const DOUBLE * PD, int n)
: Name (str), scored (PD, n) {}//Use object names for containment
For inheriting classes, the new version of the constructor uses the member initialization list syntax, which uses the class name instead of the member name to identify the constructor:
Student (const char * str, const DOUBLE * PD, int n)
: std::string (str), Arraydb (PD, N) {}//use class names for inheritance
The member initialization list uses std::string (str) instead of name (str). This is the second major difference between the inclusion and the private inheritance.
2. Methods to access the base class
When using private inheritance, the methods of the base class can only be used in methods of derived classes. But sometimes you might want the base class tool to be public. For example, you can use the average () function in a class declaration. As with inclusions, for this purpose, you can use the private student::average () function in the public student::average () function, which contains the use of objects to invoke methods:
Double Student::average () const
{
if (scores.size () > 0)
return Scores.sum ()/scoresh.size ();
Else
return 0;
}
However, private inheritance makes it possible to invoke a method of the base class using the class name and the parse operator:
Double Student::average () const
{
if (arraydb::size () > 0)
return Arraydb::sum ()/arraydb::size ();
Else
return 0;
}
In summary, using the include is to invoke the method using the object name, while private inheritance uses the class name and scope resolution operator to invoke the method.
3. Accessing base class objects
When a derived class wants to use the base class object itself, for example, the containing version of the student class implements the name () method, which returns a String object member name, but with private inheritance, the string object has no name. So how does the code for the Student class access the internal string object?
The answer is to use coercion type conversions. Because the student class is derived from the string class, you can convert the student object to a string object by forcing the type conversion: A string object with the result of inheritance. As explained earlier in this book, pointer this points to the object used to invoke the method, so *this is the object used to invoke the method, in this case, an object of type student. To avoid calling the constructor to create a new object, you can use the coercion type conversion to create a reference.
Const string & Student::name () cosnt
{
Return (cosnt string &) *this;
}
The preceding method returns a reference to a string object that inherits from the student object that is used to invoke the method.
4. Accessing the base class's friend function
Explicitly qualifying a function name with a class name is not suitable for a friend function, because friends do not belong to the class. However, you can invoke the correct function by explicitly converting to a base class. For example, for the following friend function definition:
Ostream & operator<< (ostream & OS, const Student & Stu)
{
Os << "Scores for" << (const string &) str << ": \ n";
...
}
If Plato is a student object, the following statement calls the above function, Stu will be a reference to Plato, and
will be a reference to cout:
cout << Plato;
The following code:
Os << "Scores for" << (const string &) Stu << ": \ n";
The Stu is explicitly converted to a String object reference, which in turn calls the function operator<< (Oshtream & const string &).
Referencing Stu is not automatically converted to a String object reference. The root cause is that in private inheritance, a reference or pointer to a derived class cannot be assigned to a base class reference or pointer without an explicit type conversion.
However, even if this example uses public inheritance, an explicit type conversion must be used, and one reason is that if you do not use a type conversion, the following code will match the friend function prototype, resulting in recursive invocation:
Os << Stu;
(Note: I think this means: when I os << Stu, he found out to be a student type, but the student type has no operator<< () method, so the function goes back to find his base class method, But his base class will find that it is actually a student type, and then call student's << method ... )
5. Using the modified Student class
......

14.2.2 whether to use inclusive or private inheritance
In general, you should use inclusions to establish has-a relationships, or you should use private inheritance if the new class needs to access the protected members of the original class, or if you need to redefine the virtual function.

14.2.3 Protection Inheritance
Protection inheritance is a variant of private inheritance. Protect and make use of the keyword protected when listing base classes:
Class student:protected std::string, protected std::valarray<double>
{ ... };

When you use protection inheritance, both the accumulated members and the protected members become protected members of the derived class. As with private inheritance, the accumulated interfaces are also available in derived classes, but not outside of the inheritance hierarchy. When you derive another class from a derived class, the main difference between private and protected inheritance is presented. With private inheritance, the third-generation class will not be able to use the accumulated interfaces, because the public methods of the base class will become private methods in the class, and when protected inheritance is used, the public methods of the base class are programmed to be protected in the second generation, so that the third generation of derived classes can use them.

14.2.4 using a using to redefine access rights
When you use protection derivation or private derivation, the public members of the base class are referred to as protected members or private members. One way to make a method of a base class available outside of a derived class is to define a derived class method that uses that base class method. For example, suppose that you want student to be able to use the sum () method of the Valarray class, you can have a sum () method of life in the declaration of the Student class, and then define the method as follows:
Double student::sum () const//Public Student method
{
return Std::valarray<double>::sum (); Use privately-inherited method
}
This enables the student class to invoke Student::sum (), which in turn applies the Valarray<double>::sum () method to the contained Valarray object (if the Arraydb typedef is in use, You can also use Arraydb instead of std::valarray<double>).
Another approach is to wrap a function call in another function call, even if you use a using declaration (like a namespace) to indicate that a derived class can use a particular base class member, even if two are private derivations. For example, suppose you want to be able to use Valarray's method min () and Max () through the student class, you can add the following using declaration in a common part of studenti.h:
Class Student:private std::string, Private std::valarray<double>
{
...
Public
Using std::valarray<double>::min;
Using std::valarray<double>::max;
};
The using declarations above make valarray<double>::min () and Valarray<double>::max () available, just as they are common methods of student:
cout << "High score:" << Ada[i].max << Endl;
Note that using declarations use only member names--no parentheses, function feature labels, and return types. For example, for the student class to be able to use the Valarray operator[] () method, the thumb dummy contains the following using declaration in the public part of the Student class declaration:
Using std::valarray>double<::operator[];
This will make two versions (Xonst and non-const) available. This allows you to delete the prototypes and definitions of student::operator[] (). The using declaration applies only to inheritance, not to contained.
There is an old-fashioned way to re-declare a base class method in a private derived class, placing the method name in the public part of the derived class, as follows:
Class Student:private std:stirng, Private std:valarray<double>
{
Public
std::valarray<double>::operator[]; Redeclare as public, just use name
}
This looks like a using declaration that does not contain a keyword using. This method has been deprecated and is about to cease to be used. Therefore, if the compiler supports a using declaration, you should use it to enable derived classes to use methods from the private base class.

"C + + Primer Plus" 14.2 Private inheritance Learning notes

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.