开发者

Doubt in one disadvantage of doing work in constructors

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.


When an instance of a subclass is created, first is called the constructor of the base class, then the constructor of the subclass.

If the base class constructor calls a virtual method then the method of the base class will be called instead of the subclass, although the instance is that of a subclass. This could be a problem.

A lot more information here: http://www.artima.com/cppsource/nevercall.html


If you inherit from the class, the methods that you override/implement will not be called in this case. So, if Employee calls work() in the constructor, then later on you come up with Hourly::work() and SalariedEmployee::work(), those won't get called. Even though they have different implementations, they'll still be treated as Employee, not their special implementations.


The constructor's job is simply to initialize your object's initial state. If you start performing tasks that rely on actions taken in virtual functions, you can get some unexpected results when subclasses start implementing these functions.


The behavior that virtual function calls aren't virtual is well-defined but very surprising, so compilers usually emit warnings.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜