构造函数中的C++虚函数

Sve*_*art 2 c++ polymorphism constructor

我正在阅读关于c ++构造函数的这篇文章

我们建议您在构造函数中调用虚函数时要小心.因为始终在派生类构造函数之前调用基类构造函数,所以在基础构造函数中调用的函数是基类版本,而不是派生类版本.在下面的示例中,构造DerivedClass导致print_it()的BaseClass实现在DerivedClass构造函数导致执行print_it()的DerivedClass之前执行:

这个例子:

    class BaseClass {
    public:
        BaseClass() {
            print_it();
        }
        virtual void print_it() {
            cout << "BaseClass print_it" << endl;
        }
    };

    class DerivedClass : public BaseClass {
    public:
        DerivedClass() {
            print_it();
        }
        virtual void print_it() {
            cout << "Derived Class print_it" << endl;
        }
    };

    int main() {

        DerivedClass dc;
    }
Run Code Online (Sandbox Code Playgroud)

这是输出:

BaseClass print_it
Derived Class print_it
Run Code Online (Sandbox Code Playgroud)

我尝试了这段代码,输出如上所述.但是我也尝试了没有virtual关键字的相同示例:

    class BaseClass {
    public:
        BaseClass() {
            print_it();
        }
        void print_it() {
            cout << "BaseClass print_it" << endl;
        }
    };

    class DerivedClass : public BaseClass {
    public:
        DerivedClass() {
            print_it();
        }
        void print_it() {
            cout << "Derived Class print_it" << endl;
        }
    };

    int main() {

        DerivedClass dc;
    }
Run Code Online (Sandbox Code Playgroud)

并得到了相同的结果.

那么有什么不同,他们警告的危险是什么?

@marked重复:

这个问题是不同的,因为consturctors都调用虚方法而不是一个调用虚方法的构造函数.

Lig*_*ica 7

没有区别.这就是危险.

如果你不知道更好,那么你可能会期望这样:

Derived Class print_it
Derived Class print_it
Run Code Online (Sandbox Code Playgroud)

期望是存在的,因为如果你调用virtual print_it()from函数Base,多态意味着你通常会得到Derived版本.

但是,当你在Base构造函数中编写它时,Base对象的一部分仍然在构造中,并且正在构造的对象的"动态类型"仍然是Base,而不是Derived.所以你没有得到通常的多态行为.

这篇文章警告你这个事实.