C + + reading notes about inheritance

Source: Internet
Author: User
Tags access properties modifiers

Recently in the C + +, and then read more about the object-oriented knowledge points, good memory is not as bad as the written, summed up the classification.

In object-oriented, inheritance is a very important basic concept. When you derive a new class from an existing class, you can extend and modify the original class.

Called the existing class is the base class, the inherited class is called the derived class.

When do you use inheritance? If two objects are is-a relationships, you can use inheritance.

Like fruit and apples. Apple (is-a) fruit, this time the fruit is the base class, the apple is the fruit derived class.

If it is not a (is-a) relationship, it is best not to use inheritance. such as the following relationship example.

Has-a Lunch (has-a) fruit, but lunch! (is-a) fruit. So it's not appropriate to inherit

Is-like-a Enemy (Is-like-a) Jackal, but the enemy! (Is-a) The Jackal. So it is not suitable for inheritance.

Is-implemented-as-a Array (is-implemented-as-a) stack, but array! (is-a) stack. So it is not suitable for inheritance.

Uses-a computer (USES-A) printer, but computer! (is-a) printer. So it is not suitable for inheritance.

The implementation of inheritance is simple, but it is quite complicated to manage the relationship between inheriting classes.

It involves constructing destructors, virtual functions & virtual function tables, static linking & dynamic linking, abstract base classes, dynamic memory allocation, and so on.

If you do not understand these mechanisms, there will be some running errors between the designed classes and their original intent, as well as memory leaks.

    • Basic implementation

The basic implementation of inheritance is very simple. When you define a class, the syntax is defined as ": Decorate's Baseline class name" after class MyClass.

Modifier has public, private, protect 3 kinds. These 3 modifiers represent 3 ways to inherit from C + +: Public inheritance, private inheritance, and protection inheritance.

For example, Simpleclass inherits the Baseclass,"class simpleclass:public baseclass" and the modifier is public, which indicates that it is publicly inherited.

Public inheritance is also the most common way.

With respect to modifiers, following a basic rule, regardless of the inheritance method, private members of the base class, private functions are not visible in derived classes.

To access them, they can only be accessed through the base class providing public or protected methods.

With 3 inheritance methods, the member access properties of the original base class are also changed.

Public inheritance: When a derived class is publicly inheriting a base class, the access restrictions of the members and functions of the base class are not changed in the derived class.

The base class was originally public, in a derived class or public.

Private inheritance: When a derived class is privately inheriting a base class, the access restrictions on the members and functions of the base class are all private to the derived class.

So if the private inherits a base class, it is equivalent to completely hiding all the members and functions in the base class.

Protection inheritance: When a derived class is privately inheriting a base class, the public access restrictions of the members and functions of the base class are all changed to protect in the derived class.

Private in the base class, or continue to remain private.

For the attention point of the Protect attribute, class data members are generally recommended for private use, rather than protect or public.

The reason is that with protect, derived classes can directly access data members that modify the base class.

member functions are useful with protect qualification, so that this member function is only exposed to derived classes and remains private to the public.

    • Constructors and destructors

The derived class needs to have its own constructor, and if you don't see the constructor, it's just the compiler quietly uses the default constructor.

Derived classes must call the constructor of the base class! So what about the constructor that calls the base class? The answer is simple, you specify which is which, if you are too lazy to specify, then call the default constructor.

How do you specify it? The list syntax can be initialized with the member.

For example, there is an artist class that records the artist's name and age. The artist class derives from a painter class.

In addition to the artist's name, the basic attributes of age, but also set a painting category properties, that the painter is best at the painting is a painting, Chinese painting, watercolor one of the.

#ifndef __cjiajia__artist__#define__cjiajia__artist__#include<iostream>
using namespacestd;enum{LIM = -};classartist{Private: CharFirstname[lim];//All artists should have a name CharLastname[lim]; unsignedintAge//all artists have their own age. Public: Artist (Const Char*FN ="None",Const Char*ln ="None", unsignedintAge =5);//constructor Function voidShowName ()Const;//Show artist's name intGetage ()Const{returnAge };//getting the artist's age voidSetage (intAge) { This->age = age; };//setting the artist's age};classPainter: Publicartist{Private: CharCategory[lim];//shows the painter's painting type. such as ink painting, painting, watercolor, etc. Public: Painter (Const Char*CT,Const Char*FN,Const Char*LN, unsignedintAge);//Constructor 1Painter (Const Char*CT,ConstArtist & Art);//Constructor 2 CharGetCategory ()Const;//get the painter's painting type voidSetcategory (Const Char(C6);//set the painter's painting type};

#endif/* Defined (__cjiajia__artist__) */

#include"Artist.h"Artist::artist (Const Char*FN,Const Char*LN, unsignedintAG) {strncpy (firstname, FN, LIM-1); Firstname[lim-1] =' /'; strncpy (LastName, LN, LIM-1); Lastname[lim-1] =' /'; Age=AG;}voidArtist::showname ()Const{cout<< FirstName <<" "<< lastname<<Endl;} Painter::P ainter (Const Char*CT,Const Char*FN,Const Char*LN, unsignedintAge ): Artist (FN, LN, age) {strncpy (category, CT, LIM-1); Category[lim-1] =' /';} Painter::P ainter (Const Char*CT,ConstArtist &art): Artist (art) {strncpy (category, CT, LIM-1); Category[lim-1] =' /';}

In the construction method of the artist class, the artist's name and age are specified. The painter class also has a name, age, and a special record of the type of paintings he specializes in.

In the painter class's constructor 1, the constructor for the artist class is explicitly called with the initialization Member list Artist (FN, LN, age).

Painter::P ainter (const char *CT, const char *FN, const char *LN, unsigned int age ): Artist (FN, LN, age)

In the Painter class constructor 2, the copy constructor of the artist class is called. In this example, the artist class does not explicitly define a copy constructor, so it calls its default copy constructor for a shallow copy.

With regard to the copy constructor, if a member variable pointer inside the artist class has requested memory through new, you need to explicitly define the copy constructor of the artist class to make a deep copy of this member.

Painter::P ainter (const char *CT, const Artist & Art): Artist (ART)
    • A special relationship between a base class and a derived class

A derived class can use a non-private method of the base class.

Painter chinesepainter ("Chinese Painting", "Pan", "Tian Shou", 74);
Chinesepainter.showname ();

A base-class pointer can point to a derived class object without an explicit type conversion. A base class reference can reference a derived class object without an explicit type conversion.

This is called up casting. A painter is an artist, but an artist is not a painter. This is the same as the logic of reality.

Painter chinesepainter ("Chinese Painting", "Pan", "Tian Shou", 74);
Artist & rt = Chinesepainter;
Artist * pt = &chinesePainter;
Rt.showname ();p t->showname ();
    • Polymorphic Public Inheritance

The same method can have different behavior in the derived class and the base class, depending on the object that called the method.

There are two important mechanisms for C + + to implement polymorphic public inheritance.

-Methods to redefine the base class in a derived class

-Using virtual methods

For example, the painter class above declares a method of a base class.

void ShowName () const; The painter class also defines a method for displaying names, while showing the artist's category of paintings

void Painter::showname () const;

{

cout << firstname<< "" << lastname<< "good" << category << Endl;

}

If the showname is not specified as the virtual method, the following code runs as follows:

Artist  chineseartist ("Qi", "Baishi", 93);
Painter chinesepainter ("Chinese Painting", "Pan", "Tian Shou", 74);
Artist & art1_ref = chineseartist;
Artist & art2_ref = Chinesepainter;

If ShowName is not the Vitrual method
Art1_ref.showname (); Using Artist::showname ()
Art2_ref.showname (); Using Artist::showname ()
If ShowName is the Vitrual method
Art1_ref.showname (); Using Artist::showname ()
Art2_ref.showname (); Using Painter::showname ()

If a method is a virtual virtual method, the program chooses the method based on the type of object that the reference or pointer points to.

If a method is not a virtual virtual method, the program chooses the method based on the type of reference or pointer.

In a base class, if the method is declared as a virtual method, it is also a virtual method in a derived class, even if it is not explicitly specified as a virtual method.

The method in the derived class method to call the base class, plus the domain-qualified modifier and the method name are called.

By convention, a base class should contain a virtual destructor! The reason is to call the destructor of the corresponding object type, and then the destructor of the base class is called automatically.

If a derived class contains destructors that perform certain operations, the base class must have a virtual destructor, even if the destructor does nothing.

    • Static and dynamic-linked virtual function tables

When a program invokes a function, the compiler determines which execution code block to use. Executing a specific block of code based on a function call is called a binder.

In the process of compiling, a union that can be completed is called a static union.

However, due to the existence of virtual functions in C + +, the compile time cannot determine which function to use, the compiler must generate code that chooses the correct virtual method when the program runs.

This is called dynamic linking.

When to use dynamic linking, when to use static-linked? The non-virtual method is statically linked and the virtual method is dynamically linked.

Most of the time, dynamic linking is good, and it allows the program to choose a method that is designed for a particular type.

However, the compiler uses static binders by default. The reason is efficiency, in order for the program to be determined at run-time, the compiler must take some methods to keep track of the base class pointers (virtual function tables), adding additional overhead.

The big God says one of the guiding principles of C + + is not to pay the price (memory or processing time) for unused features.

So if you want to redefine a method of a base class in a derived class, set it to a virtual method, and the no should be set to a non-virtual method.

The way the compiler handles virtual functions is to add a hidden member to each object. A pointer to an array of function addresses is saved in the hidden member.

This array is known as the virtual function table (virtual table, VTBL). The address of a virtual function declared for a class object is stored in a virtual function table.

You can see that the more virtual functions are defined, the larger the array. When a virtual function is called, the compiler goes to the table to find the address of the function.

    • Prevent redefinition

If the following method is re-showname (int type) const in the painter class, then the ShowName () of the artist class will be hidden.

When the painter class calls ShowName (), a compilation error occurs.

void showname (int type) const; The painter class also defines a method for displaying names, while showing the artist's category of paintings

void painter::showname (int type) const;

{

cout << firstname<< "" << lastname<< "good" << category << Endl;

}

So summarize 2 rules of thumb:

1. The method of redefining inheritance should be identical to the prototype of the base class. The exception is the return value of the function if it is a reference or pointer to a base class, it is OK to modify it to point to a reference or pointer to a derived class.

This attribute is called return type covariance (covariance of return types).

2. If the functions in the base class are overloaded, and you want to redefine their implementations in the derived class, you should redefine all the base class versions in the derived class.

If lazy only defines one version, the other overloaded version will be hidden.

    • Abstract base class (ABC)

The reason for defining abstract classes is that some of them, though is-a, are not efficient at solving problems by inheriting them.

Like circles and ellipses. A circle requires only a radius value to describe the size and shape, and it does not require a long and short half axis B. It is also possible to take care of this by assigning the same value to members A and B, but it is not necessary to cause information redundancy.

This time you can put the features of circles and ellipses into an ABC, derived from the ABC and the Ellipse class.

Syntactically, a class that has at least one pure virtual function is an abstract class and cannot create an instance object of an abstract class.

Pure virtual function is to add a =0 at the end of a virtual function, which means that the function is pure virtual function.

For example, virtual double area () const = 0;

    • Dynamic memory allocation

If a class member is initialized with new, then the associated copy constructor is defined, and the overloaded assignment operator =.

That's all for the time being.

C + + reading notes about inheritance

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.