I was reading Google C++ Style Guide, and got confused in the Doing Work in Constructors part. One of the cons of doing heavy work in constructor is:
If the work calls virtual functions, these calls will not get dispatched to the subclass implementations. Future modification to your class can quietly introduce this problem even if your class is not currently subclassed, causing much confusion.
I didn't understand what it means. Could someone provide an explanation and why this may be considered a disadvantage?
I'm blatantly ripping off some example code from the Wikipedia Virtual function page:
#include <iostream>
#include <vector>
class Animal {
public:
virtual void eat() const {
std::cout << "I eat like a generic Animal." << std::endl;
}
virtual ~Animal() {
}
};
class Wolf : public Animal {
public:
void eat() const {
std::cout << "I eat like a wolf!" << std::endl;
}
};
class Fish : public Animal {
public:
void eat() const {
std::cout << "I eat like a fish!" << std::endl;
}
};
If you call eat()
inside the Animal
constructor, it will call the Animal
eat()
function every time. Even when you create a Wolf
or a Fish
object, since the Animal
constructor will complete before the subclass object is initialized, the overriding eat
functions won't exist yet.
This is a disadvantage because it can cause confusion between what's expected and what actually happens. If I override eat
then create an object of my subclass, I expect my overridden function to be called, even from an Animal
reference. I expect it because that's what happens when the call is made explicitly by code outside the constructor. The behavior is different inside the constructor, causing me to scratch my head in bewilderment.
When an object is being constructed, the constructors for base classes are called first. Since the derived class hasn't been initialized yet, any calls to virtual methods during the base class constructor won't have a derived class object to work on.
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