Deep analysis of pure virtual function and abstract class _c language in C + + programming

Source: Internet
Author: User
Tags gety

C + + pure virtual function detailed explanation

Sometimes specifying a member function as a virtual function in a base class is not a requirement for the base class itself, but rather a function name in the base class, given the needs of the derived class, with the specific functionality left to the derived class to define as needed.

A pure virtual function is a function that is "initialized" to 0 when declaring a virtual function. The general form of declaring a pure virtual function is

  virtual function type function name (parameter table column) = 0;

A few points to note about pure virtual functions:

    • Pure virtual function has no function body;
    • The last side of the "= 0" does not mean that the return value of the function is 0, it only plays a formal role, telling the compiler system "This is pure virtual function";
    • This is a declaration statement with a semicolon at the end.

Pure virtual functions cannot be invoked unless they have the function's name and function. It simply notifies the compiling system that "declare a virtual function here, and leave it to the derived class to define". After you provide a definition for this function in a derived class, it can have functions that can be invoked.

The function of a pure virtual function is to retain the name of a function in the base class for its derived class, so that the derived class defines it as needed.

You cannot implement polymorphism if there is no reserved function name in the base class. If a pure virtual function is declared in a class and the function is not defined in its derived class, the virtual function is still a pure virtual function in the derived class.

Another discussion on C + + abstract classes

If you declare a class, you can generally use it to define an object. But in object-oriented programming, there are often classes that are not used to generate objects. The only purpose of defining these classes is to use it as a base class to establish derived classes. They are provided to the user as a basic type, and the user defines derived classes that vary in functionality based on their needs. Use these derived classes to create objects.

For example, car manufacturers often provide customers with the chassis of trucks (including engines, transmission parts, wheels, etc.), which can be assembled into different functions such as wagons, buses, engineering vehicles or buses. The chassis itself is not a vehicle, it has to be processed to become a vehicle, but it is the basic component of the vehicle. It corresponds to the base class. In the modernization of production, most of the use of specialized production methods, the full use of specialized factory production of components, processing set to become a new breed of products. The manufacturer of the bus will never be finished by the factory from manufacturing the engine to producing the tires and making the carriages. In fact, the basic components of different brands of computers are the same or similar. This concept is very important for software development. When a good software worker develops a large software, he never writes the program code from beginning to end, he makes full use of existing resources (such as Class library) as the basis for his work.

This type of class, which is not used to define an object and is used as an inheritance only as a basic type, is called an abstract class (abstract class), which is often referred to as the base class (abstract base Class). All classes that contain pure virtual functions are abstract classes. Because pure virtual functions cannot be invoked, classes that contain pure virtual functions cannot establish objects.

The function of an abstract class is to act as a common base class for a class family, or to provide a common interface for a class family. A class hierarchy can of course not contain any abstract classes, and each level of classes is actually available and can be used to create objects.

However, many good object-oriented systems have an abstract class at the top of the hierarchy, or even several layers at the top of which are abstract classes.

If all the pure virtual functions of a base class are defined in a new class that is derived from an abstract class, these functions are given functionality and can be invoked. This derived class is not an abstract class, but rather a concrete class (concrete class) that can be used to define objects.

If all pure virtual functions are not defined in a derived class, this derived class is still an abstract class and cannot be used to define objects. Although an abstract class cannot define an object (or an abstract class cannot be instantiated), you can define a pointer variable that points to the abstract class data. When a derived class becomes a concrete class, you can use the pointer to point to the derived class object and then invoke the virtual function through the pointer to implement the operation of the polymorphism.

Several examples of C + + pure virtual functions and abstract classes
here is a complete program that inserts some textual instructions for readability. The procedure is as follows:

Part (1)

#include <iostream>
using namespace std;
Declare abstract base class shape class
shape
{public
:
  Virtual float area () const {return 0.0;}//virtual function
  virtual float Volume () const {return 0.0;}//virtual function
  virtual void shapename () const = 0;//pure virtual function
};

The Shape class has 3 member functions and no data members. 3 member functions are declared as virtual functions, where shapename is declared as a pure virtual function, so shape is an abstract base class. The role of the Shapename function is to output the name of a specific shape (such as dots, circles, cylinders), which is closely related to the corresponding derived class, which should not be defined in the base class, but should be defined in the derived class. So declare it as a pure virtual function. Shape is an abstract base class, but it can also include the definition part of some members. The two functions in the class, area, and volume (volume) include the function body so that it returns a value of 0 (since the point's area and volume are considered to be 0). Since the area and volume functions are no longer redefined in the point class, the area and volume functions are not declared as pure virtual functions. The area and volume functions of the shape class are inherited in the point class. These 3 functions are used in each derived class.

Part (2)

Declares the point class
point:public shape//point is a common derived class of Shape
{public: Point
  (float=0,float=0);
  void SetPoint (float, float);
  float GetX () const {return x;}
  float GetY () const {return y;}
  virtual void Shapename () const {cout<< "point:";} Redefine the virtual function
  friend Ostream & operator << (ostream &,const Point &);
Protected:
  float x,y;
Define point class member function point
::P oint (float a,float b)
{x=a;y=b;}
void Point::setpoint (float a,float b)
{x=a;y=b;}
Ostream & operator << (ostream &output,const point &p)
{
  output<< "[" <<p.x< < "," <<p.y<< "]";
  return output;
}

Point inherits 3 member functions from shape, since "points" have no area or volume, so you do not have to redefine areas and volume. Although these two functions are not used in the point class, the point class inherits the two functions from the shape class so that their derived classes inherit them. The Shapename function is a pure virtual function in the shape class and is defined in the point class. The point class also has its own member functions (SetPoint, GetX, GetY) and data members (x and Y).

Part (3)

//Declare Circle class class Circle:public point {public:circle (float x=0,float y=0,float r=0);
  void Setradius (float);
  float Getradius () const;
  Virtual float area () const; virtual void Shapename () const {cout<< "Circle:";}
Redefine the virtual function friend Ostream &operator << (ostream &,const Circle &);
Protected:float radius;
}; Declare Circle class member function circle::circle (float a,float b,float R):P oint (a,b), radius (r) {} void Circle::setradius (float R): Radius (r) {} float Circle::getradius () const {return radius;} float Circle::area () const {return 3.14159*radius*radius;} ostream &am P;operator << (ostream &output,const Circle &c) {output<< "[<<c.x<<]," <<c.y
  << "], r=" <<c.radius;
return output; }

In the Circle class, you redefine the area function, because you need to specify a formula for the circle size. Because a circle has no volume, you do not have to redefine the volume function, but rather inherit the volume function from the point class. The Shapename function is a virtual function that needs to be redefined to give new content (if not redefined, the Shapename function in the point class is inherited). In addition, the Circle class also has its own newly added member functions (Setradius, Getradius) and data members (RADIUS).

Part (4)

//Declare Cylinder class class Cylinder:public Circle {public:cylinder (float x=0,float Y=0,floa
  T r=0,float h=0);
  void SetHeight (float);
  Virtual float area () const;
  Virtual float volume () const;
  virtual void Shapename () const {cout<< "Cylinder:";
}//the virtual function is redefined by friend ostream& operator << (Ostream&,const cylinder&);
Protected:float height;
}; Defines the Cylinder class member function Cylinder::cylinder (float a,float b,float r,float h): Circle (a,b,r), height (h) {} void Cylinder:: SetHeight (float h) {height=h} float Cylinder::area () const{return 2*circle::area () +2*3.14159*radius*height;} float Cy Linder::volume () const{return Circle::area () *height} ostream &operator << (ostream &output,const Cylind er& cy) {output<< "[" <<cy.x<< "," <<cy.y<< "], r=" <<cy.radius<< ", h="
  <<cy.height;
return output; }

The cylinder class is derived from the Circle class. Because of the surface area and volume of the cylinder, it is necessary to redefine the areas and volume functions. Virtual function Shapename also need to be redefined. In addition, the cylinder class also has its own member function setheight and data member radius.

Part (5)

Main function int main () {point point (3.2,4.5);//Set point class object Point Circle Circle (2.4,1.2,5.6);
  Establish the Circle class object Circle Cylinder Cylinder (3.5,6.4,5.2,10.5);
  Establish the Cylinder class object cylinder point.shapename ();
  Static Association cout<<point<<endl; Circle.shapename ();
  Static Association cout<<circle<<endl; Cylinder.shapename ();
  Static Association cout<<cylinder<<endl<<endl; Shape *pt; Define base class pointer pt=&point; The pointer points to the Point class object Pt->shapename (); Dynamic Association cout<< "x=" <<point.getx () << ", y=" <<point.gety () << "\narea=" <<pt->
  Area () << "\nvolume=" <<pt->volume () << "\ n"; pt=&circle; The pointer points to the Circle class object Pt->shapename (); Dynamic Association cout<< "x=" <<circle.getx () << ", y=" <<circle.gety () << "\narea=" <<pt->
  Area () << "\nvolume=" <<pt->volume () << "\ n"; pt=&cylinder; The pointer points to the cylinder class object Pt->shapename (); Dynamic Association cout<< "x=" <<cylinder.getx ();< ", y=" <<cylinder.gety () << "\narea=" <<pt->area () << "\nvolume=" <<pt->
  Volume () << "\ n";
return 0;
 }

Call the function in the main function and output the result. First, the Point class object Point,circle class object circle and Cylinder class object cylinder are defined respectively. The Shapenanme function is then called by the object name point, Circle, and cylinder, which is a static association in which the Shapename function of which class should be called is determined at compile time. You can also verify that the object is initialized correctly by outputting the information of each object with the overloaded transport character "<<".

Then define a pointer variable pt that points to the base class Shape object, so that it points to 3 derived class objects point, Circle and cylinder, and then invokes the functions via the pointer, such as Pt->shapename (), PT->area (), pt- >volume (). It is then through dynamic Association to determine which function should be called separately. Output information for different classes of objects, respectively.

The results of the program operation are as follows:

point:[3.2,4.5] (Point class object points data: coordinates of dots)
circle:[2.4,1.2], r=5.6 (Circle class object Circle data: Center and RADIUS)
cylinder:[ 3.5,6.4], r=5.5, h=10.5 (Cylinder class object cylinder data: center, RADIUS, and high)

point:x=3.2,y=4.5 (Output point class object points data: coordinates of dots)
area= 0 (area of point)
volume=0 (volume of point)

circle:x=2.4,y=1.2 (Output Circle class object Circle data: center coordinates)
area=98.5203 (area of Circle)
volume =0 (volume of a circle)
cylinder:x=3.5,y=6.4 (Output Cylinder class object Cylinder data: center coordinates)
area=512.595 (area of the circle)
volume=891.96 ( The volume of a cylinder)

The following conclusions can be further clarified from this example:
A base class that contains one or more pure virtual functions is an abstract base class. Abstract base classes cannot and do not have to define objects.
Unlike a normal base class, an abstract base class is generally not an abstraction of a realistic object (for example, a circle (Circle) is an abstraction of thousands of actual circles), and it can have no physical or other practical meaning.
In the hierarchy of a class, the top-level or topmost layers can be abstract base classes. Abstract base class embodies the generality of all kinds in the family, and the member functions of all kinds of Chinese Communists are declared in the abstract base class.
Abstract base classes are common interfaces of this class family. Alternatively, multiple classes derived from the same base class have the same interface.
Distinguish between static and dynamic associations. If you call a virtual function through an object name (such as Point.shapename ()), you can determine the virtual function of which class is invoked at compile time, and therefore belong to a static association. If you call a virtual function through a base class pointer (such as PT->shapename ()), in the compile phase, it is not possible to determine which class's virtual function is invoked from the statement itself, only when the PT points to a class of objects in order to determine which class's virtual function is invoked, so it is a dynamic association.
If a virtual function is declared in a base class, a function in a derived class that has the same function name, function type, number of parameters, and type as the function is a virtual function (whether or not a virtual declaration is used in a derived class).
Using virtual functions increases the extensibility of the program. Separate the declaration of the class from the use of the class. This is especially important for software developers who design class libraries.

Developers design a variety of classes, but do not provide users with source code, users can not know how the class is declared, but you can use these classes to derive their own classes. Using virtual functions and polymorphism, the programmer's attention is focused on dealing with universality, while the execution environment deals with particularity.

Polymorphism leaves the details of the operation to the designers of the class (many of whom are professionals) to complete, and letting programmers (class users) Just do some macro work, telling the system what to do without having to think about what to do, greatly simplifies the coding of the application and greatly reduces the burden on the programmer, Also reduces the learning and use of C + + programming difficulties, so that more people can quickly access the C + + program design Gate.

Related Article

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.