当前位置:网站首页>Bingc (inheritance)
Bingc (inheritance)
2022-06-26 05:40:00 【Yuetun】
Table of contents title
- Inherit
- polymorphic
Inherit
Inheritance mode
- public Inheritance mode ,
In base class public The access rights of decorated members in subclasses are still public,
In base class protected The access rights of decorated members in subclasses are still protected,
In base class private Decorated members are not visible in subclasses — Can't be directly accessed - protected Inheritance mode
In base class public The permission of the decorated member in the subclass becomes protected
In base class protected The permissions of modified members in subclasses have not changed , namely protected
In base class private Decorated members are not visible in subclasses , That is, it cannot be accessed directly - private Inheritance mode
In base class public Modify the access rights of members in subclasses private
In base class protected The access rights of decorated members in subclasses are still private
In base class private Decorated members are not visible in subclasses — Can't be directly accessed - Use keywords class The default inheritance method is private, Use struct The default inheritance method is public
Assignment conversion of base class and derived class objects ---- Assignment compatibility rules ----
It must be public Only under the inheritance mode of
- It can be used directly Subclass objects assign values to base class objects , But the other way around, you can't ( You cannot assign a value to a subclass object using a base class object )
- In order to make The pointer to the base class points to the subclass The object of , But the other way around, you can't ( You cannot directly point to a base class object with a pointer to a subclass ), If you must point to It has to be forced to turn
- have access to The reference of the base class refers to the subclass object , But not vice versa ( You cannot use a subclass reference to reference a base class object )
Scope in inheritance
- In the inheritance system, both base and derived classes have Independent scopes .
- There are... In subclasses and superclasses Member with the same name ( Functions and variables ), Subclass members will block direct access from the parent class to members with the same name , This situation is called hide , Also called redefinition .( In subclass member functions , have access to Base class :: Base class members Show the access )
- It should be noted that if it is a hidden member function , It only needs the same function name to form a hidden .
Such as :
// Subclass
Derived d;
d.func(10);
d.Base::func();
d._b = 100;
d.Base::_b = 200;
- Note that in practice, it is better not to define members with the same name in the inheritance system .
Default member functions for derived classes
- Constructor for a derived class You must call the base class The constructor of initializes that part of the base class . If the base class There is no default Constructor for , Must be in the... Of the derived class constructor The initialization list phase shows the call .
- The copy constructor of a derived class must Call the base class The copy structure of completes the copy initialization of the base class .( The base class is undefined , Subclasses don't matter , The base class defines , Subclasses are also generally defined )
- Of a derived class operator= Must call The base class operator= Finish copying the base class .
- The destructor of the derived class will be called after Automatically call Base class destructors clean up base class members . Because this ensures that derived classes ; Object to clean up derived class members first and then base class members .
class Base
{
public:
Base(int b)
: _b(b)
{
}
Base(const Base& b)
: _b(b._b)
{
}
Base& operator=(const Base& b)
{
if (this != &b)
{
_b = b._b;
}
return *this;
}
~Base()
{
cout << "Base::~Base()" << endl;
}
protected:
int _b;
};
class Derived : public Base
{
public:
Derived(int b = 10, int d = 20)
: Base(b)
, _d(d)
{
}
Derived(const Derived& d)
: Base(d)
, _d(d._d)
{
}
Derived& operator=(const Derived& d)
{
if (this != &d)
{
// 1. First call the assignment operator overload of the base class to assign values to some members of the base class
Base::operator=(d);
// 2. Assign values to the newly added members of the subclass itself
_d = d._d;
}
return *this;
}
~Derived()
{
cout << "Derived::~Derived()" << endl;
// After the compiler compiles the destructor of the subclass
// An assembly statement calling the base class destructor will be inserted after the last statement of the subclass destructor
// call ~Base();
}
protected:
int _d;
};
- When initializing a derived class object, first call the base class constructor, and then call the derived class constructor .
- The derived class object destructs and cleans up to call the pie first
Which members of the base class are inherited by subclasses
- Member variables
Common member variable : All members of the base class and ordinary member variables are inherited by subclasses
Static member variable : Phi inherits the same static member variable in multiple subclasses , In the whole inheritance system , There is only one static member - Member functions
Ordinary member functions ---- All member functions of the base class are inherited by subclasses
Static member functions :: Be inherited
Default member function : Construct copy construct assignment operator overload destructor ( Ambivalence ) - Friendship You can't Inherit , That is, base class friends cannot access private and protected members of subclasses
Multiple inheritance
The base class part is on , The subclass part is under , The order of multiple base class parts in the subclass object is the same as that of the base class in the inheritance list : Before each base class in the inheritance list must Add inheritance permission , Otherwise, it would be Default Inherited permissions for
class D : public C1, public C2
{
public:
int _d;
};
diamond inheritance

There is ambiguity
Solution :
1. To clarify

2. Virtual inheritance ( Used in diamond inheritance to solve the ambiguity problem in diamond inheritance )( heavy )(windows vs2013)
class B
{
public:
int _b;
};
class D : virtual public B
{
public:
D()
{
}
public:
int _d;
};
The difference between virtual inheritance and ordinary single inheritance ?
1. The object model is inverted ( Subclass variables first , In the base class variable )
2. There are many objects 4 Bytes ( Call offset table address or virtual base table pointer )
3. If D Constructor is not explicitly defined , Then the compiler will generate , If D The constructor is defined , Then the compiler must modify the constructor
Generate || Purpose of revision : Go to the front of the object 4 Fill and discard data in bytes
step :
1. Before fetching objects 4 Contents in bytes , namely : Offset table 2 Take the backward offset in the address space 4 The content after the byte — Offset use
3. Combine the offset to _b assignment
The illustration :
polymorphic
Concept : Generally speaking , It's a lot of forms , The specific point is to complete a certain behavior , When different objects complete, they will produce different states .
classification
- Static polymorphism ( Static binding || Early binding ): The program is in During compilation The behavior of the function has been determined , Typical representative : function overloading 、 template function
- Dynamic polymorphism ( Dynamic binding || Late binding ): When the program is running , To determine the behavior of the function , That is to say The compilation phase cannot determine Exactly which function to call
Dynamic polymorphism condition
- Must be in Inherit Under the system of
- There must be... In the base class Virtual functions ( By virtual Keyword modified member functions are called virtual functions ), stay Subclass The virtual function in the base class must be rewrite
- Virtual function call : Must pass Pointer or reference to the base class To call
Polymorphism manifests
rewrite
a. Must be in an inherited system
b. The member function of the base class must be a virtual function
c. Of virtual functions of subclasses and base classes Prototype ( Return value type function name ( parameter list )) It must be as like as two peas. ( exception :
- Return value types can be different — Base class 1 A virtual function must return a base class 2 Object pointer or reference ; Subclass 1 Virtual functions must return subclasses 2 A pointer or reference to an object ( Base class 1 And base classes 2 Can be different , But it must be paired with Subclasses )
- Different function names , But it has to be Destructor
)
d. And access rights It doesn't matter.
Override the hidden contrast with the same name

c++11 New characteristics
- override
// override: C++11 New keyword added in , Purpose : In the compilation phase , To detect override
// Whether the modified function overrides the virtual function corresponding to its base class
// override Only virtual functions can be modified , Can only modify virtual functions of subclasses
// If the rewrite is successful -- Compile and pass
// Otherwise, compile and report an error
class Base
{
public:
virtual void Test1Func()
{
cout << "Base::TestFunc()" << endl;
}
};
class Derived : public Base
{
public:
virtual void Test1Func()override
{
cout << "Base::TestFunc()" << endl;
}
};
- final
Modify function
// final: Modify function
// Only virtual functions can be modified
// It is generally used to modify subclass virtual functions , Purpose : This virtual function cannot be overridden by a derived class of a subclass
class B
{
public:
virtual void f()
{
cout << "B::f()" << endl;
}
// Compiler error
//void f1()final
//{}
// Not recommended
virtual void f2()final
{
}
};
// demand : stay D In the following subclasses , Don't want to let f Virtual functions are rewritten again
class D : public B
{
public:
virtual void f()final
{
cout << "D::f()" << endl;
}
};
class E : public D
{
public:
/* // Compile failed , because f stay D Middle quilt final Modify the , namely :E Can't be used in a base class f Rewrite virtual void f() { cout << "E::f()" << endl; }*/
};
decorator
// final: You can also modify classes
// effect : This class cannot be inherited
class B final
{
public:
int func()
{
cout << "B::func()" << endl;
}
};
class D : public B
{
};
abstract class
Write... After the virtual function =0, Then this function is Pure virtual function . A class containing pure virtual functions is called abstract class ( Also called interface class ), abstract class Cannot instantiate object . A derived class cannot instantiate an object after inheritance , Only rewrite pure virtual functions , A derived class can instantiate an object . Pure virtual functions specify that derived classes must override , In addition, pure virtual functions embody interface inheritance .
Interface inheritance and implementation inheritance
Inheritance of ordinary functions is an implementation inheritance , The derived class inherits the base class function , You can use functions , Inherited is the implementation of the function . Virtual function inheritance is an interface inheritance , The derived class inherits the interface of the virtual function of the base class , The purpose is to rewrite , Reach polymorphism , Inherited is the interface . So if you don't implement polymorphism , Don't define functions as virtual functions _
class Shape
{
public:
// Pure virtual function
virtual double GetArea() = 0;
virtual double GetCircumference() = 0;
};
Realization principle
Take this as an example
// Conclusion : If the class contains virtual functions , No matter how many virtual functions there are , The size of class objects is much larger 4 Bytes
class Base
{
public:
Base(int b = 10)
: _b(b)
{
cout << "Base()" << endl;
}
virtual void f1()
{
cout << "Base::f1()" << endl;
}
virtual void f3()
{
cout << "Base::f3()" << endl;
}
virtual void f2()
{
cout << "Base::f2()" << endl;
}
int _b;
};
Class object model with virtual functions

If the class contains virtual functions ( It has nothing to do with the number ), The compiler will give objects more increase 4 Bytes And more 4 Bytes at the beginning of the object ----- What's in memory is Virtual table address , The virtual table address is filled in when the object is constructed -----> Filled in the constructor ( Constructor if not explicitly implemented : The compiler will generate a default constructor for the class ; Constructor if explicitly implemented : The compiler will modify the constructor implemented by the user ---- Before adding to the object 4 A statement that stores virtual table addresses in bytes )
Virtual table construction principle — rewrite ( Cover )
Generate... In the compile phase , The essence is an array of function pointers
Basic class virtual function table construction rules :
- According to the virtual function in The order of declaration in the class Fill in the virtual table in turn
Construction rules of subclass virtual table :
2. Copy the contents of the virtual table of the base class into the virtual table of the subclass ( At this point, the base class and subclass do not use the same virtual table )
3. If the subclass overrides the virtual function of the base class , Replace the entry address of the virtual function of the base class at the same offset position in the virtual table with the virtual function of the subclass itself
4. Virtual functions newly added to subclasses are placed at the end of the virtual table in the order of their declarations in the class
verification
The construction method produces
Conclusion : If the compiler feels it needs it , Will generate
1. Classes and objects ︰ If B Class contains A Class object ,B Constructor is not explicitly defined ,A It defines no parameter or all default construction methods , Then the compiler will give B Class generates the default constructor
⒉. Inherit : If B Inherited from A,A There are no parameters or all default constructors defined in ,B No constructor is explicitly defined , The compiler will give B The construction method of generating parameterless
3. Virtual inheritance : If B Virtual inherits from A,B No constructor is explicitly defined , The compiler will give B Class generates the default constructor , Purpose : In order to be in front of the object 4 Bytes The address of the virtual base table
4. Class contains virtual functions : If the class does not explicitly define any constructors , The compiler will generate a default constructor for this class , Purpose : To be in front of an object 4 Bytes The address of the virtual table
Disassembly of polymorphic parent-child classes

Multi inheritance virtual table
Virtual function table analysis
Memory layout of objects
Common questions
1. The following statement about pure virtual functions , The right is ( a)
A: Classes that declare pure virtual functions cannot instantiate objects B: The class that declares a pure virtual function is a virtual base class
C: Subclasses must implement pure virtual functions of the base class D: A pure virtual function must be an empty function
2. The correct description of virtual functions is ( b)
A: The virtual function of derived class has different number and type of parameters from that of base class B: An inline function cannot be a virtual function
C: The derived class must redefine the virtual function of the base class D: The virtual function can be a static Function of type
3. hypothesis A There are virtual functions in class ,B Inherited from A,B rewrite A Virtual function in , There are no virtual functions defined , be (d )
A:A Class object 4 Bytes store the virtual table address ,B Class object 4 Bytes are not virtual table addresses
B:A Class objects and B Class object 4 Each byte stores the address of the virtual base table
C:A Class objects and B Class object 4 The virtual table addresses stored in bytes are the same
D:A Classes and B The number of virtual functions in the class virtual table is the same , but A Classes and B Class does not use the same virtual table
#include<iostream>
using namespace std;
class A{
public:
A(char *s) {
cout<<s<<endl; }
~A(){
}
};
class B:virtual public A {
public:
B(char *s1,char*s2):A(s1) {
cout<<s2<<endl; }
};
class C:virtual public A {
public:
C(char *s1,char*s2):A(s1) {
cout<<s2<<endl; }
};
class D:public B,public C {
public:
D(char *s1,char *s2,char *s3,char *s4):B(s1,s2),C(s1,s3),A(s1)
{
cout<<s4<<endl;}
};
int main() {
D *p=new D("class A","class B","class C","class D");
delete p;
return 0; }

A
A:class A class B class C class D B:class D class B class C class A
C:class D class C class B class A D:class A class C class B class D
class A {
public:
virtual void func(int val = 1){
std::cout<<"A->"<< val <<std::endl;}
virtual void test(){
func();}
};
class B : public A {
public:
void func(int val=0){
std::cout<<"B->"<< val <<std::endl; }
};
int main(int argc ,char* argv[])
{
B*p = new B;
p->test();
return 0; }
B
A: A->0 B: B->1 C: A->1 D: B->0
6. Can static members be virtual functions ? answer : You can't , Because static member functions do not this The pointer , Type of use :: How member functions are called , Cannot access virtual function table , So static member functions cannot be put into the virtual function table .
7. Can a constructor be a virtual function
Suppose the constructor can be a virtual function , Then the constructor is also in the virtual table , That is, the constructor can only be called through the virtual table , In the construction mode, the object is only given before 4 The address of the virtual table in bytes , The constructor does not call , Before the object 4 Bytes without virtual table pointer —> Cannot find virtual table —> Unable to find the entry address of the constructor
8. Is it faster for objects to access ordinary functions or virtual functions ? answer : First, if it's an ordinary object , It's as fast . If it's a pointer object or a reference object , The ordinary function called is faster , Because the composition is polymorphic , When calling a virtual function at runtime, you need to look up the virtual function table .
9. At what stage is the virtual function table generated , Where does it exist ? answer : The virtual function table is generated at the compilation stage , In general, there are code snippets ( The constant area ) Of .
10. Can a destructor be a virtual function ? In what scenario is a destructor a virtual function ? answer : Sure , And it's best to define the destructor of the base class as a virtual function .
边栏推荐
- Security problems in wireless networks and modern solutions
- How to make your big file upload stable and fast?
- MySQL source code reading (II) login connection debugging
- 新的征程
- 最后一次飞翔
- C XX management system
- Introduction to lcm32f037 series of MCU chip for motor
- Some doubts about ARP deception experiment
- Yunqi lab recommends experience scenarios this week, free cloud learning
- Old love letters
猜你喜欢
Posting - don't get lost in the ocean of Technology

Gram 矩阵
![C# 40. Byte[] to hexadecimal string](/img/3e/1b8b4e522b28eea4faca26b276a27b.png)
C# 40. Byte[] to hexadecimal string

Command line interface of alluxio

Learn cache lines and pseudo sharing of JVM slowly

Henkel database custom operator '~~‘

Official image acceleration

Sofa weekly | open source person - Yu Yu, QA this week, contributor this week

Mongodb image configuration method

LeetCode_ Binary search tree_ Simple_ 108. convert an ordered array to a binary search tree
随机推荐
适配器模式
Mongodb image configuration method
The difference between get and post in small interview questions
C# 40. Byte[] to hexadecimal string
Cyclic displacement
【活动推荐】云原生、产业互联网、低代码、Web3、元宇宙……哪个是 2022 年架构热点?...
Leetcode114. 二叉树展开为链表
Redis discovery bloom filter
小小面试题之GET和POST的区别
Lesson 4 serial port and clock
SQL query time period content
BOM文档
Pytorch中自己所定义(修改)的模型加载所需部分预训练模型参数并冻结
Fedora alicloud source
SOFA Weekly | 开源人—于雨、本周 QA、本周 Contributor
Introduction to lcm32f037 series of MCU chip for motor
data = self._ data_ queue. get(timeout=timeout)
LeetCode_ Binary search tree_ Simple_ 108. convert an ordered array to a binary search tree
DOM文档
【ARM】在NUC977上搭建基于boa的嵌入式web服务器
