当前位置:网站首页>Bingc (inheritance)

Bingc (inheritance)

2022-06-26 05:40:00 Yuetun

Last one

Inherit

Example

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

  1. 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 )
  2. 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
  3. 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

  1. In the inheritance system, both base and derived classes have Independent scopes .
  2. 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 )
  3. 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;
  1. 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

  1. 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 .
  2. 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 )
  3. Of a derived class operator= Must call The base class operator= Finish copying the base class .
  4. 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;
};
  1. When initializing a derived class object, first call the base class constructor, and then call the derived class constructor .
  2. The derived class object destructs and cleans up to call the pie first

Which members of the base class are inherited by subclasses

  1. 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
  2. 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 )
  3. 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

 Insert picture description here
There is ambiguity

Solution :

1. To clarify

 Insert picture description here

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 :
 Insert picture description here

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

When the program is running , Point to objects of different classes according to the pointer or reference of the base class , Select the appropriate virtual function to call

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 :

  1. 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 )
  2. 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

 Insert picture description here

c++11 New characteristics

  1. 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;
    }
};

  1. 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;
};

Example

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

 Insert picture description here
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 :

  1. 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

 Insert picture description here

Multi inheritance virtual table

Multiple inheritance
 Insert picture description here

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; }

 Insert picture description here
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 .

原网站

版权声明
本文为[Yuetun]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/177/202206260530190950.html