What is the meaning of the reintroduce and override directives in Delphi?

后端 未结 4 1599
余生分开走
余生分开走 2020-12-28 13:42

What is the difference between the override and reintroduce directives? And when should I not use the

4条回答
  •  遥遥无期
    2020-12-28 14:35

    The reference to Jim's answer, which was excellent BTW, only described the when and where to use the directives. Another part of the answer is why are they needed anyway? Many languages get along just fine without them, right? When designing aspects of the Delphi Object Pascal Language, OOP (Object Oriented Programming) had been in the mainstream for several years. During this time it was observed that using many of the languages that had adopted those concepts (Turbo Pascal, C++, etc..) to develop application frameworks suffered from what I called the "version 2" problem.

    Suppose you developed an awesome framework using language X and released it as version 1. Your users raved at all it could do and it became heavily used. Flush with success, you decide to release version 2 with even more awesomeness. You specifically made sure it was fully backward compatible. Suddenly, you users started reporting strange behaviors. Their own virtual methods were being called at strange times. Many reported that their old code would not compile with the new version. Strange. All the same objects, methods, and functionality still remained. All you did was add a few virtual methods to some base classes, some new object types, and some new optional functionality. What happened?

    The override and reintroduce directives serve to eliminate this problem by requiring that in order to actually override a virtual method you must use the override directive in place of the virtual directive. If you happen to introduce your own virtual method that has the same name as one of your ancestors' virtual methods, the compiler now warns you, but will still do the right thing. In this case, using reintroduce, not only suppresses that warning, it also serves to document in the source you intended to do that.

    Without the override and reintroduce directives, you would not be able to continually evolve your framework without fear of breaking all your users. And if your users had to make massive modifications every time a new version is released, then they would be loathe to adopt the new version. Finally, using "override" also allows the framework designer to change the type of virtual in the ancestors without breaking user code. For instance, in Delphi many methods are marked "dynamic" which is a table-based runtime method lookup form of polymorphism. It's doesn't perform quite as fast as a regular virtual so it is usually used for methods that are rarely overridden and/or are responses to user actions where the extra overhead is never noticed. Suppose in V1 of the framework a method was marked "dynamic" but in practice it ended up being overridden and called more than you intended. In V2, you could change it to "virtual" without fear of user's code being broken.

    Delphi's Object Pascal language isn't the only language to recognize this problem. C# requires the use of an "override" directive for the exact same reason. The C++ standards committee is finally recognizing the problem and are modifying the language to support it... sort of. In C++, if a method's name and parameter list matches an ancestor's virtual, then it is an override (even if you don't say "virtual" on the descendant!). For the upcoming new C++ standard, if you specify "virtual" and the signatures don't match then it is a new virtual method introduced on current class. If there is a signature match with the ancestor and the writer didn't intend to override, then the "new" keyword is used to tell the compiler that this is a new virtual for this class.

提交回复
热议问题