If you are a C ++ProgramClerk, 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:
Class debuggingnow {public: Virtual void F1 (); Virtual void F2 (); Virtual void F3 ();};
In project2, you call its virtual function:
Pdbgnow-> F2 ();
Then you add a virtual function to this class due to some requirement:
Class debuggingnow {public: Virtual void F1 (); Virtual void f1_5 (); Virtual void F2 (); Virtual void F3 ();};
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:
Before pdbgnow-> F2 (), It is compiled to call the second virtual function in the debuggingnow class. Because it is a virtual function, it actually calls a function similar to pdbgnow-> 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.
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, compile allCodeThe time spent is very large. With a virtual function, you may have to wait for several hours to see the final result, which is unacceptable.
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. In this way, you need to add a virtual function, 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:
Class debuggingnow {public: Virtual void F1 (); Virtual void F2 (); Virtual void F3 (); Virtual void dummyvirtualfunction1 (); Virtual void dummyvirtualfunction2 (); virtual void dummyvirtualfunction3 (); Virtual void dummyvirtualfunction5 (); Virtual void dummyvirtualfunction6 ();};
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.