何时在构造函数中调用虚函数是安全的 [英] When is it safe to call a virtual function in a constructor

查看:157
本文介绍了何时在构造函数中调用虚函数是安全的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码,我真的想从一个构造函数调用一个虚方法。我知道这被认为是不安全的,我知道足够的对象构造也理解为什么。我也没有遇到这些问题。目前我的代码正在工作,我认为应该很好,但我想确定。

I have some code where I really want to call a virtual method from a constructor. I know this is considered unsafe, and I know enough about object construction to also understand why. I also am not experiencing these problems. Currently my code is working and I think it should be fine, but I want to make sure.

这里是我在做什么:

我有一些类层次结构,有一个普通的公共函数,只是转发到私有虚拟方法,像往常一样。但是我想在构建我的对象时调用这个公共方法,因为它正在将所有数据填充到对象中。我将绝对确定这个虚拟调用来自叶类,因为从类层次结构的任何其他部分使用这个虚方法根本没有意义。

I have some class hierarchy and there is a normal public function which just forwards to a private virtual method, as usual. However I do want to call this public method upon construction of my objects, because it is filling all data into the object. I will be absolutely sure that this virtual call comes from the leaf class, because using this virtual method from any other part of the class hierarchy simply does not make sense at all.

所以在我看来,对象创建应该完成一旦我做虚拟调用,一切都应该很好。还有什么可能出错吗?我想我必须标记这一部分的逻辑与一些大的意见,解释为什么这个逻辑应该永远不会移动到任何基本clases,即使它看起来像它可以移动。但是除了其他程序员的愚蠢,我应该很好,不应该吗?

So in my opinion the object creation should be finished once I am doing the virtual call and everything should be fine. Is there still anything that could go wrong? I guess I'll have to mark this part of the logic with some big comments to explain why this logic should never ever be moved to any of the base clases, even though it looks like it could be moved. But other than stupidity of other programmers I should be fine, shouldn't I?

推荐答案

- 在构造函数或析构函数中提取虚函数!然而,它的行为可能是混乱,因为它可能不会做预期。当类的构造函数被执行时,对象的静态和动态类型是构造函数的类型。也就是说,虚函数将从不分派到另一个派生类的覆盖。除此之外,虚拟分派实际上是有效的。当通过基类指针或引用调用虚函数时,正确地调度当前构造函数或破坏类中的override。例如(可能有打字错误,因为我目前不能这个代码):

It is absolutely safe to call any non-abstract virtual function in the constructor or the destructor! However, its behavior may be confusing as it may not do what is expected. While the constructor of a class is executed, the static and dynamic type of the object is the type of the constructor. That is, the virtual function will never be dispatched to the override of a further derived class. Other than that, virtual dispatch actually works: e.g. when calling a virtual function via a base class pointer or reference correctly dispatches to the override in the class being currently constructor or destructed. For example (probably riddled with typos as I currently can't this code):

#include <iostream>
struct A {
    virtual ~A() {}
    virtual void f() { std::cout << "A::f()\n"; }
    void g() { this->f(); }
};
struct B: A {
    B() { this->g(); } // this prints 'B::f()'
    void f() { std::cout << "B::f()\n"; }
};
struct C: B {
    void f() { std::cout << "C::f()\n"; } // not called from B::B()
};

int main() {
    C c;
}

也就是说,您可以直接或间接调用虚函数构造函数或类的析构函数,如果您不想将虚函数分派给另一个派生函数。你甚至可以做到这一点是虚函数是在给定类中的抽象,只要它被定义。但是,调用未定义的抽象函数将导致运行时错误。

That is, you can call a virtual function, directly or indirectly, in the constructor or a destructor of a class if you don't want the virtual function to be dispatched to a further derived function. You can even do this is virtual function is abstract in the given class as long as it is defined. However, having an undefined abstract function being dispatched to will cause a run-time error.

这篇关于何时在构造函数中调用虚函数是安全的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆