在构造函数虚函数,为什么语言有什么不同? [英] Virtual functions in constructors, why do languages differ?

查看:210
本文介绍了在构造函数虚函数,为什么语言有什么不同?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C ++中,当一个虚函数是从构造它并不像一个虚函数中调用。我想,大家谁遇到过的第一次很惊讶,但转念一想这是有道理的,如果派生的构造函数尚未运行的对象的不可以又一个的来源的这样如何才能导出函数被调用?的preconditions还没有被设置的机会。例如:

In C++ when a virtual function is called from within a constructor it doesn't behave like a virtual function. I think everyone who encountered for the first time was surprised but on second thought it makes sense, if the derived constructor hasn't yet run the object is not yet a derived so how can a derived function be called? The preconditions haven't had the chance to be set up. Example:

class base {
public:
    base()
    {
        std::cout << "foo is " << foo() << std::endl;
    }
    virtual int foo() { return 42; }
};

class derived : public foo {
    int* ptr_;
public:
    derived(int i) : ptr_(new int(i*i)) { }
    // The following cannot be called before derived::derived due to how C++ behaves, 
    // if it was possible... Kaboom!
    virtual int foo()   { return *ptr_; } 
};

这是完全一样的Java和.NET但他们选择了走另一条路,是唯一的原因的至少惊喜的原则?

你认为哪是正确的选择?

Which do you think is the correct choice?

推荐答案

有一个在语言如何定义对象的续航时间有着根本的区别。在Java和.NET对象成员的任何构造函数运行之前,是在这一点上对象的生命时开始的零/零初始化。所以,当你进入构造你已经有了一个初始化的对象。

There's a fundamental difference in how the languages define an object's life time. In Java and .Net the object members are zero/null initialized before any constructor is run and is at this point that the object life time begins. So when you enter the constructor you've already got an initialized object.

在C ++中的对象寿命只有开始时的构造完成(尽管成员变量和基类的构造完全启动前)。这说明当虚函数被调用,也就是为什么,如果有在构造函数的身体异常的析构函数不运行的行为。

In C++ the object life time only begins when the constructor finishes (although member variables and base classes are fully constructed before it starts). This explains the behaviour when virtual functions are called and also why the destructor isn't run if there's an exception in the constructor's body.

与对象的生命周期在Java / .NET定义的问题是,它很难以确保对象总是满足其不变的,而不必把在特殊情况下初始化对象,但构造函数无法运行时的。用C ++定义的问题是,你有这样奇怪的时期,其中的对象是在中间状态并没有完全建成。

The problem with the Java/.Net definition of object lifetime is that it's harder to make sure the object always meets its invariant without having to put in special cases for when the object is initialized but the constructor hasn't run. The problem with the C++ definition is that you have this odd period where the object is in limbo and not fully constructed.

这篇关于在构造函数虚函数,为什么语言有什么不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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