In manual memory management contexts, the situation can be more complex, particularly in relation to static dispatch. If an object of type Wolf is created but pointed to by an Animal pointer, and it is this Animal pointer type that is deleted, the destructor called may actually be the one defined for Animal and not the one for Wolf, unless the destructor is virtual. This is particularly the case with C++, where the behavior is a common source of programming errors if destructors are not virtual.
== Derived class constructor calls virtual function ==
- Calling virtual base function within derived constructor, if function is not defined within derived class, are captured by the linker as being unresolved symbol - which is as expected.
- Although '''calling virtual base function''' '''through a base wrapper''', would not be captured by compiler nor linker, and '''is fatal in C++ at runtime''' (some runtimes will issue pure virtual zero function call error)
This is is due to way code is compiled/linked. Within the scope of class definition, calling base wrapper function is fully resolved symbol, whether same or separate translation unit, but the base function calling unresolved virtual never known until runtime (at least compiler does not see that far).
These things should not happen when code is written at least within same solution, compilers do loop unrolls and various variable optimizations, it should also do class construction tree check especially for virtual functions.
Example below shows this in action (virtual function test1 is defined within Derived class two levels apart)<syntaxhighlight lang="c++" line="1">
struct Base {
virtual void test1() = 0;
void test1_wrap() { // wrapper
test1();
}
virtual ~Base() {} // warning C5204, care about virtual destructors? - read below
};
struct Mid : Base {
virtual void test2() = 0;
Mid() {
//test1(); // linker LNK2019, unresolved symbol
test1_wrap(); // compiles all good - fatal runtime (on construct)
}
};
struct Derived : Mid {
void test1() {}
void test2() {}
};
int main() {
Derived d;
}
</syntaxhighlight>
== See also ==
|