当前位置:网站首页>Understand the concepts of virtual base class, virtual function and pure virtual function (turn)
Understand the concepts of virtual base class, virtual function and pure virtual function (turn)
2022-04-23 14:06:00 【JokerYourMemory】
introduction
I haven't written a conceptual article for a long time , Because I think these conceptual things are all in books, and they are very detailed. It's useless to write them down , I had a whim to write today Write , Let's discuss the virtual base class 、 Virtual function and pure virtual function , It's easy to feel confused at the sight of the name . But don't worry. After reading this article, you will understand .
Text
virtual base class
Look at a piece of code before explaining what it does
{
public:
int iValue;
};
class B:public A
{
public:
void bPrintf(){cout<<"This is class B"<<endl;};
};
class C:public A
{
public:
void cPrintf(){cout<<"This is class C"<<endl;};
};
class D:public B,public C
{
public:
void dPrintf(){cout<<"This is class D"<<endl;};
};
void main()
{
D d;
cout<<d.iValue<<endl; // error , Ambiguous access
cout<<d.A::iValue<<endl; // correct
cout<<d.B::iValue<<endl; // correct
cout<<d.C::iValue<<endl; // correct
}
You can see from the code that the class B C All inherit classes A Of iValue member , So the class B C All have a member variable iValue , And category D And inherited B C, Such kind D There is a member with the same name iValue( One is from the class B Inherited from , One is from the class C Inherited from ). Call in main function d.iValue Because class D There is a member with the same name iValue The compiler does not know the call From whom iValue So there is the problem of ambiguity . The correct approach should be to add the scope qualifier d.B::iValue Indicates that the call is from B Class inherited iValue. however class D There are multiple instances of iValue Example , It takes up memory space . therefore C++ The concept of virtual base class is quoted in , To solve this problem .
{
public:
int iValue;
};
class B:virtual public A
{
public:
void bPrintf(){cout<<"This is class B"<<endl;};
};
class C:virtual public A
{
public:
void cPrintf(){cout<<"This is class C"<<endl;};
};
class D:public B,public C
{
public:
void dPrintf(){cout<<"This is class D"<<endl;};
};
void main()
{
D d;
cout<<d.iValue<<endl; // correct
}
Precede the inherited class with virtual Keyword indicates that the inherited class is a virtual base class , Its inherited member retains only one instance in the derived class . for example iValue This member , From the class D From this point of view , It is from class B With the class C inherited , And category B C From the class A inherited , But they only keep one copy . Therefore, the middle note is called in the main function. d.iValue Not when There will be mistakes .
Virtual functions
Or look at the code first
{
public:
void funPrint(){cout<<"funPrint of class A"<<endl;};
};
class B:public A
{
public:
void funPrint(){cout<<"funPrint of class B"<<endl;};
};
void main()
{
A *p; // Defines a pointer to the base class
A a;
B b;
p=&a;
p->funPrint();
p=&b;
p->funPrint();
}
What do you think the output of this code is ? Some people may answer right away funPrint of class A And funPrint of class B Because the first output is a reference class A Reality of Example ah , The second output is the reference class B It's a good example . Then I tell you it's wrong to think so , The answer is funPrint of class A And funPrint of class A As for why output Such a result is beyond the scope of this paper ; Just remember , No matter which class the referenced instance is, when you call it, the system will call the method of the class to which the lvalue object belongs . for instance The above code class A B There is one. funPrint function , because p It's a A Pointer to class , So whether you're going to p Pointer to class A Or class B, The final functions called are classes A Of funPrint function . This is the static couplet , The compiler has been determined at the time of compilation . But what if I want to dynamically decide which function to call according to different instances ? This requires the use of Virtual functions ( That is, dynamic couplets )
{
public:
virtual void funPrint(){cout<<"funPrint of class A"<<endl;};
class B:public A
{
public:
virtual void funPrint(){cout<<"funPrint of class B"<<endl;};
};
void main()
{
A *p; // Defines a pointer to the base class
A a;
B b;
p=&a;
p->funPrint();
p=&b;
p->funPrint();
}
Add before the member function of the base class virtual Keyword indicates that this function is a virtual function , The so-called virtual function is that you are not sure which function to call when compiling , It's a dynamic decision to be adjusted Which function , To implement a virtual function, the function name of the derived class must be the same as that of the base class , Parameter name, parameter type, etc. should also be the same as the base class . But in derived classes virtual Keywords can be omitted , Also table This is an imaginary function . Let's solve the code , Declare a pointer to a base class ( Must be a base class , Not the other way around )p, hold p Pointing class A Example a, call funPrint function , this The system will judge when p The type of instance pointed to , If it is A Class is called A Class funPrint function , If it is B Class is called B Class funPrint function .
Pure virtual function
It's better to call it abstract class than pure virtual function , It simply declares a function but does not implement it , Let derived classes implement it , In fact, it's easy to understand .
class Vehicle
{public:
virtual void PrintTyre()=0; // Pure virtual functions are defined in this way
} ;
class Camion: public Vehicle
{
public:
virtual void PrintTyre(){cout<<"Camion tyre four"<<endl;};
} ;
class Bike: public Vehicle
{
public:
virtual void PrintTyre(){cout<<"Bike tyre two"<<endl;};
} ;
void main()
{
Camion c;
Bike b;
b.PrintTyre();
c.PrintTyre();
}
Code above , Defines a vehicle class (Vehicle), There is a function in the class that can print the number of tires of the vehicle , However, the number of tires in many vehicles is naturally uncertain , therefore Just define it as a pure virtual function , That is, just define the function name without implementing it , class Camion Inherited Vehicle And implemented the code inside , Print out 4 A tire .Bike Class is the same . There is one thing that needs attention , Pure virtual functions cannot be realized , However, pointers can be declared .
summary
virtual base class
1, A class can be used as a virtual base class in a family of classes , Also used as a non virtual base class .
2, In the object of the derived class , A virtual base class with the same name produces only one virtual base class sub object , A non virtual base class generates its own sub objects .
3, Virtual base class sub objects are initialized by the constructor of the most derived class by calling the constructor of the virtual base class .
4, The most derived class refers to the class specified when creating an object in the inheritance structure .
5, The member initialization list of the constructor of the derived class must list the calls to the virtual base class constructor ; If not listed , It means that the default constructor of the virtual base class is used .
6, The member initialization list of the constructor in the derived class directly or indirectly derived from the virtual base class should list the calls to the virtual base class constructor . But only the most derived used to build objects The constructor of class calls the constructor of virtual base class , The calls to the constructor of the virtual base class listed in all base classes of the derived class are ignored in execution , So as to ensure that the virtual base class sub objects Initialize only once .
7, When both virtual base class and non virtual base class constructors are called in a member initialization list , The constructor of a virtual base class executes before the constructor of a non virtual base class .
Virtual functions
1, Virtual functions are non static 、 Non inline member function , Not a friend function , But virtual functions can be declared as friend functions in another class .
2, Virtual function declaration can only appear in the function prototype declaration of class definition , It cannot be declared when the function body of the member function is implemented .
3, No matter how many times a virtual function is inherited by the public , It still retains the properties of its virtual function .
4, If a member function in a class is described as a virtual function , Then the member function may have different implementations in the derived class . When the member function is used to manipulate the object identified by the pointer or reference , Dynamic binding can be adopted for calling this member function .
5, After defining the virtual function , The pointer to the base class declared in the program can point to its derived class . In the process of execution , This function can constantly change the object it points to , Different calls Version of member function , And these actions are implemented dynamically at runtime . Virtual functions fully embody the dynamic polymorphism of object-oriented programming . Pure virtual function Version of member function , And these actions are implemented dynamically at runtime . Virtual functions fully embody the dynamic polymorphism of object-oriented programming .
Pure virtual function
1, When a meaningful implementation of a virtual function cannot be given in a base class , You can declare it as a pure virtual function , Its implementation is left to the derived class .
2, The function of pure virtual function is to provide a consistent interface for derived classes .
3, Pure virtual functions cannot be realized , However, pointers can be declared .
版权声明
本文为[JokerYourMemory]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231401090972.html
边栏推荐
猜你喜欢
随机推荐
帆软实现一个单选按钮,可以统一设置其他单选按钮的选择状态
帆软中单元格中隔行变色以及数量大于100字体变大变红设置
生产环境——
JDBC详解
BUG_me
查询2013年到2021年的数据,只查询到2020的数据,遇到了这个问题所进行的解决办法
As a junior college student, I studied hard in closed doors for 56 days, won Ali offer with tears, five rounds of interviews and six hours of soul torture
websocket
报表FCRA考试题集及答案(错了11题)
微信小程序基于udp协议与esp8266进行通信
PyMySQL
Restful WebService和gSoap WebService的本质区别
微信小程序setInterval定时函数使用详细教程
Go语言 RPC通讯
Lin Lin, product manager of Lenovo: network failure of local network operator in Tianjin. The background server of Zui system can't work normally for the time being
Program compilation and debugging learning record
Nodejs安装及环境配置
jsp学习1
帆软中使用if else 进行判断-使用标题条件进行判断
Jacob print word