I was wondering how can one explain this mechanism:
class Base{
class Other;
virtual void test() = 0;
};
class Other: Base{
virtual void test() override;
};
void Other::test(){ /*do something*/}
It looks like I have a base class called Base. It contains of a nested class which inherits from the Base. So if I call:
Base obj;
obj.test(); <-- it trigers the test() function from the Other class, doesn't it?
What is the difference between the given example and the following:
class Base{
virtual void test() = 0;
};
class Other: Base{
virtual void test() override;
};
void Other::test(){ /*do something*/}
what would be the benefit of hidding the Other class in the Base class?
class Base{ virtual void test() = 0; }; Base obj; // #0
#0 is ill-formed as Base is an abstract class, as it has at least one pure abstract member function.
Abstract class
Defines an abstract type which cannot be instantiated, but can be used as a base class.
A pure virtual function is a virtual function whose declarator has the following syntax:
declarator virt-specifier(optional) = 0[...] An abstract class is a class that either defines or inherits at least one function for which the final overrider is pure virtual.
Dynamic dispatch on polymorphic objects happens when you are dispatching to a virtual function from a base pointer or reference, which (for the specific runtime call) references a derived object.
In the following example:
struct Base {
virtual void test() const = 0;
};
struct A final : public Base {
void test() const override {}; // #1
};
struct B final : public Base {
void test() const override {}; // #2
};
void f(Base const& b) {
b.test(); // #3
}
the call to the virtual member function test() at #3 can dispatch to either A::test() or B::test(), depending on the argument to the function f.
f(A{}); // 'test()' call in 'f' dispatches to #1
f(B{}); // 'test()' call in 'f' dispatches to #2
what would be the benefit of hidding the Other class in the Base class?
In your original example, the Base class declares a nested class (but does not define it) to itself, meaning the Other class declared in Base is not the same as the Other class that derives from it.
The declaration of class Base::Other at line 2 in your first code example, has nothing to do with the declaration of class Other in line 5 of your first code example.
That is, the forward declaration of Base::Other does not match class Other.
There is benefit in having nested classes (for example, some implementations of the pimpl idiom do that), but to define the nested class, you would have to define it with:
class Base::Other {...}; // explicit specification of Base here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With