Reposted from: the point where virtual functions are broken
Problem:
If you are a C ++ programmer, I think you may have encountered this situation:
In debug, a step into function is called, but the result jumps into function B.
Why is it clearly displayed in the call stack, that is, it directly enters function B. You may wonder if the system is faulty, the compiler is faulty, or the debugger is faulty ~~~
In fact, those things are not so error-prone. Let's first check whether your A and B functions are virtual functions of the same class. If yes, this is most likely because you have modified the virtual function and have not fully compiled it.
Not clear yet? Let's look at this example. assume that you have a class named debuggingnow in project1, which has three virtual functions:
In project2, you call its virtual function:
Then you add a virtual function to this class due to some requirement:
Only compile project1. When pdbgnow-> F2 () is called in project2, you will find the situation described at the beginning of this article: F2 () is called (), the result is f00005 (). The reasons are as follows:
Pdbgnow-> F2 () is compiled to call the second virtual function in the debuggingnow class. Because it is a virtual function, the actual call is similarPdbgnow-> vtable [1]. Because f1_5 becomes the second function in the virtual table after f1_5 () is added, Project 2, pdbgnow-> F2 () is not re-compiled () the call is not updated to the correct pdgbnow-> vtable [2], so the real call is the function f1_5 (), which has nothing to do with the function name.
Solution:
You may think that this "low-level error" won't happen to you at all. There are at least two ways to solve this problem:
- Add the virtual function to the end forever
- Always compile all projects
Indeed, these two tactics are effective to a certain extent, but let's take a closer look:
- Adding the virtual function to the end is always useful for the above example. However, if other classes are derived from the debuggingnow class, even if you add the virtual function to the end of the debuggingnow class, it will disrupt the virtual table of its derived class.
- Always compile all projects. This is indeed an insurance method. However, in a large system, it takes a lot of time to compile all the code. With a virtual function added, you may have to wait for several hours to see the final result, this is what we don't want to bear.
Therefore, for a core base class in a large system that is in the active modification period, a good operation method is to allocate enough virtual functions in advance, so when you need to add virtual functions, you only need to modify an existing one. You don't need to rebuild it on a large scale. You just need to compile the code that uses this virtual function. The saved time is considerable:
07 |
virtual void dummyvirtualfunction1(); |
08 |
virtual void dummyvirtualfunction2(); |
09 |
virtual void dummyvirtualfunction3(); |
10 |
virtual void dummyvirtualfunction5(); |
11 |
virtual void dummyvirtualfunction6(); |
With dummyvirtualfunction, new virtual functions will no longer need to compile modules that use old virtual functions... Reduced build time!
You can use dummyvirtualfunction flexibly not only to add virtual functions, but also to delete virtual functions.
Remember two operation principles:
- When dummyvirtualfunction is used up quickly, some resources are pre-allocated.
- At the end of this stage of development, the base class tends to be stable and the redundant dummyvirtualfunction can be removed.