Object oriented programming (OOP) is not only a model of program programming with object concept, but also an abstract policy of program development.
Three characteristics of object-oriented -- encapsulation, inheritance and polymorphism
encapsulation
The objective things are encapsulated into abstract classes, and classes can only allow their own data and methods to be operated by trusted classes or objects, and hide the untrusted information. Keywords: public, protected, private. Do not write. The default is private.
- public Members: can be accessed by any entity
- protected Member: only accessible by subclasses and member functions of this class
- private Member: can only be accessed by member function, friend class or friend function of this class
inherit
- Base class (parent class) - > derived class (subclass)
Polymorphism:
Polymorphism can be divided into static polymorphism and dynamic polymorphism. Static polymorphism includes function overloading and generic programming. Dynamic is the use of virtual functions.
- Polymorphism, that is, multiple states (forms). In short, we can define polymorphism as the ability of messages to be displayed in many forms.
- Polymorphism is based on encapsulation and inheritance.
- C + + polymorphism classification and Implementation:
- Ad hoc polymorphism (compile time): function overload and operator overload
- Subtype Polymorphism (runtime): virtual function
- Parameter polymorphism (compile time): class template, function template
- Coercion Polymorphism (compile time / run time): basic type conversion and user-defined type conversion
Static polymorphism (compile time / early binding)
class A { public: void do(int a); void do(int a, int b); };
Dynamic polymorphism (Runtime / late binding)
- Virtual function: modify the member function with virtual to make it a virtual function
- Dynamic binding: dynamic binding occurs when a virtual function is called using a reference or pointer to the base class
be careful:
- The object of the derived class can be assigned to the pointer or reference of the base class, and vice versa
- Ordinary functions (non class member functions) cannot be virtual functions
- A static function cannot be a virtual function
- The constructor cannot be a virtual function (because the virtual table pointer is not in the memory space of the object when calling the constructor, and the virtual table pointer cannot be formed until the constructor call is completed)
- The inline function cannot be a virtual function that represents polymorphism. See the following explanation: Can a virtual function be an inline function?
Dynamic polymorphism use
C + + foundation - understanding of dynamic polymorphism - Zhihu
class Shape // Shape class { public: virtual double calcArea() { ... } virtual ~Shape(); }; class Circle : public Shape // Circular class { public: virtual double calcArea(); ... }; class Rect : public Shape // Rectangular class { public: virtual double calcArea(); ... }; int main() { Shape * shape1 = new Circle(4.0); Shape * shape2 = new Rect(5.0, 6.0); shape1->calcArea(); // Call the method inside the circular class shape2->calcArea(); // Call the method inside the rectangular class delete shape1; shape1 = nullptr; delete shape2; shape2 = nullptr; return 0; }
virtual destructor
The virtual destructor is to solve the problem that the pointer of the base class points to the derived class object, and delete the derived class object with the pointer of the base class.
Virtual destructor usage
class Shape { public: Shape(); // Constructor cannot be a virtual function virtual double calcArea(); virtual ~Shape(); // virtual destructor }; class Circle : public Shape // Circular class { public: virtual double calcArea(); ... }; int main() { Shape * shape1 = new Circle(4.0); shape1->calcArea(); delete shape1; // Because the Shape has a virtual destructor, when deleting to release memory, call the subclass destructor first, and then the base class destructor to prevent memory leakage. shape1 = NULL; return 0; }
Pure virtual function
Pure virtual function is a special virtual function. It can not give a meaningful implementation of virtual function in the base class, but declare it as pure virtual function, and its implementation is left to the derived class of the base class.
virtual int A() = 0;
- If a virtual function is declared in a class, the function is implemented, even if it is empty. Its function is to enable the function to be overridden in its subclass. In this way, the compiler can use late binding to achieve polymorphism. A pure virtual function is just an interface, a declaration of a function, which should be left to be implemented in a subclass.
- Virtual functions can not be overridden in subclasses; However, pure virtual functions must be implemented in subclasses to instantiate subclasses.
- The class of virtual function is used for "implementation inheritance". It inherits the implementation of the parent class while inheriting the interface. Pure virtual functions focus on the unity of the interface, and the implementation is completed by subclasses.
- A class with pure virtual functions is called an abstract class. This class cannot directly generate objects, but can only be used after it is inherited and its virtual functions are rewritten. After the abstract class is inherited, the subclass can continue to be an abstract class or an ordinary class.
- Virtual base class is the base class in virtual inheritance. See virtual inheritance below for details.
Virtual function pointer, virtual function table
- Virtual function pointer: in the object containing virtual function class, it points to the virtual function table, which is determined at run time.
- Virtual function table: in the program read-only data section (. rodata section), see: Target file storage structure )If the derived class implements a virtual function of the base class, the virtual function pointer of the original base class will be overwritten in the virtual table and created according to the class declaration at compile time.
Virtual inheritance
Virtual inheritance is used to solve the diamond inheritance problem under the condition of multiple inheritance (waste of storage space and ambiguity).
The underlying implementation principle is related to the compiler. It is generally implemented through virtual base class pointer and virtual base class table. Each virtual inherited subclass has a virtual base class pointer (occupying the storage space of a pointer, 4 bytes) and a virtual base class table (not occupying the storage space of class objects) (it should be emphasized that the virtual base class will still have a copy in the subclass, but only one copy at most, not out of the subclass); when the subclass of virtual inheritance is inherited as the parent class, the virtual base class pointer will also be inherited.
In fact, vbptr refers to the virtual base table pointer, which points to a virtual table, in which the offset address between the virtual base class and this class is recorded; through the offset address, the virtual base class members are found, and virtual inheritance does not need to maintain the common base class (virtual base class) like ordinary multi inheritance Two copies of the same, saving storage space.
Virtual inheritance, virtual function
- Similarities: both use virtual pointers (both occupy the storage space of the class) and virtual tables (both do not occupy the storage space of the class)
- Differences:
- Virtual inheritance
- The virtual base class still exists in the inherited class and only occupies storage space
- The virtual base class table stores the offset of the virtual base class from the directly inherited class
- virtual function
- Virtual functions do not occupy storage space
- The virtual function table stores the virtual function address
- Virtual inheritance
Template class, member template, virtual function
- Virtual functions can be used in template classes
- The member template of a class (whether ordinary or class template) (which is the member function of the template itself) cannot be a virtual function
Template classes are as follows:
Abstract class, interface class, aggregation class
- Abstract class: a class containing pure virtual functions
- Interface class: an abstract class containing only pure virtual functions
- Aggregation class: users can directly access its members, and has a special initialization syntax form. Meet the following characteristics:
- All members are public
- No constructor defined
- There is no in class initialization
- There are no base classes and no virtual functions
#include <iostream> #include <string> using namespace std; template <class T1,class T2> class Pair { public: T1 key; //keyword T2 value; //value Pair(T1 k,T2 v):key(k),value(v) { }; bool operator < (const Pair<T1,T2> & p) const; }; template<class T1,class T2> bool Pair<T1,T2>::operator < (const Pair<T1,T2> & p) const //Member function operator of Pair< { //"Small" means that the keyword is small return key < p.key; } int main() { Pair<string,int> student("Tom",19); //Instantiate a class pair < string, int > cout << student.key << " " << student.value; return 0; } When instantiating a class template, as shown in line 21, the parameters in the real type parameter table are specific type names, such as string,int Or other class names (e.g CStudent)They are used to replace the type parameters in the type parameter table in the class template definition one by one. Class template name <Real type parameter table>It becomes the name of a specific class. When the compiler compiles to line 21, it uses string replace Pair In template T1,use int replace T2,The rest is left as it is, so a new class is automatically generated. How does the compiler handle the name of this class? You don't need to know, you can think its name is Pair <string, int>. It can also be said that, student The type of object is Pair<string, int>. Pair<string, int> Class member functions are naturally replaced Pair In the member function of the template T1,T2 Got it. The process that the compiler generates a class from a class template is called instantiation of a class template. The class instantiated from a class template is called a template class.
Function template as a member of class template
#include <iostream> using namespace std; template <class T> class A { public: template <class T2> void Func(T2 t) { cout << t; } //Member function template }; int main() { A<int> a; a.Func('K'); //The member function template Func is instantiated a.Func("hello"); return 0; }
Abstract class, interface class, aggregation class
- Abstract class: a class containing pure virtual functions
- Interface class: an abstract class containing only pure virtual functions
- Aggregation class: users can directly access its members and have special initialization syntax. It meets the following characteristics:
- All members are public
- No constructor defined
- There is no in class initialization
- There are no base classes and no virtual functions