当前位置: 首页 > 面试题库 >

构造函数中的虚函数,为什么语言不同?

茹照
2023-03-14
问题内容

在C ++中,从构造函数内部调用虚拟函数时,它的行为不像虚拟函数。

我认为第一次遇到这种行为的每个人都会感到惊讶,但第二次认为这是有道理的:

只要派生的构造函数没有被执行的对象是 不是 又一个 衍生 实例。

那么如何调用派生函数呢?前提条件还没有建立的机会。例:

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

class derived : public base {
    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完全相同,但是他们选择了另一种方式,这可能是 产生最少惊讶原则 的唯一原因吗?

您认为哪个是正确的选择?


问题答案:

语言定义对象生命周期的方式存在根本差异。在Java和.Net中,在运行任何构造函数之前,将对象成员初始化为零/空,并且此时对象生命周期开始。因此,当您输入构造函数时,您已经有了一个初始化的对象。

在C
++中,对象生存期仅在构造函数完成时开始(尽管成员变量和基类在开始之前已完全构建)。这解释了调用虚函数时的行为,以及在构造函数主体中存在异常的情况下为何不运行析构函数的原因。

Java / .Net对象生存期定义的问题在于,很难确保对象始终满足其不变性,而不必在初始化对象但构造函数未运行时进行特殊处理。C
++定义的问题在于,您有一个奇数时期,其中对象处于不确定状态且未完全构造。



 类似资料:
  • 主要内容:多种方式创建和初始化结构体——模拟构造函数重载,带有父子关系的结构体的构造和初始化——模拟父级构造调用Go语言的类型或结构体没有构造函数的功能,但是我们可以使用结构体初始化的过程来模拟实现构造函数。 其他编程语言构造函数的一些常见功能及特性如下: 每个类可以添加构造函数,多个构造函数使用函数重载实现。 构造函数一般与类名同名,且没有返回值。 构造函数有一个静态构造函数,一般用这个特性来调用父类的构造函数。 对于 C++ 来说,还有默认构造函数、拷贝构造函数等。 多种方式创建和初始化结构

  • 本文向大家介绍请你回答一下为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数?相关面试题,主要包含被问及请你回答一下为什么析构函数必须是虚函数?为什么C++默认的析构函数不是虚函数?时的应答技巧和注意事项,需要的朋友参考一下 将可能会被继承的父类的析构函数设置为虚函数,可以保证当我们new一个子类,然后使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。  

  • 问题内容: 我对此代码有疑问:https : //github.com/reactjs/redux/blob/master/examples/async/containers/App.js 特别: 我猜这是一个两部分的问题。 为什么我需要将句柄更改设置为类的实例,我不能只对handleChange使用静态函数并直接在类中调用它 ? 我不知道这是怎么回事: 谢谢 问题答案: 以相反的顺序回答… 返回

  • 问题内容: 必须使用无参数构造函数(像Hibernate这样的工具会在此构造函数上使用反射来实例化对象)。 我得到了这个手挥手的答案,但是有人可以进一步解释吗?谢谢 问题答案: hibernate,并且通常通过反射创建对象的代码用于创建类的新实例。此方法需要一个公共的无参数构造函数才能实例化该对象。对于大多数用例,提供无参数构造函数不是问题。 有一些基于序列化的技巧可以解决没有no-arg构造函数

  • 我正在尝试编写一个Python实用程序,将Oracle的RAW字节字符串(作为字符串)转换为Guid,反之亦然。我试图重用我在C#中构建的同一个实用程序中的算法,但是从同一个字节数组构造一个和一个会产生不同的Guid/UUID。它们是一样的,不是吗?我读过UUID只是一个更好的术语。 在C#中,我有一个字节数组,< code>byte_array如下所示: 在 Python 中,我有一个字节数组,

  • 问题内容: 我是Java编程语言的初学者,最近我研究了 构造函数 不能在Java中继承,有人可以解释 为什么 吗? 问题答案: 简而言之,构造函数不能被继承,因为在子类中它具有​​不同的名称(子类的名称)。 您只能执行以下操作: 相反,方法是使用“相同名称”继承的,可以使用。 理由如下:继承构造函数没有多大意义,因为类A的构造函数意味着创建类型A的对象,而类B的构造函数意味着创建类B的对象。 不过