【问题标题】:why newly instance(object) is created when constructor exits? [closed]为什么构造函数退出时会创建新的实例(对象)? [关闭]
【发布时间】:2014-09-13 17:58:57
【问题描述】:

我在采访中被问到为什么构造函数退出时会创建一个新对象?

我说过,当我们为任何类声明对象时,内存是在运行时在堆栈或堆中创建的。一旦创建了内存,就会调用构造函数,当它完成时,它会返回新对象,因为空间被构造函数初始化的内容和新对象填充。

如果有人能解释一下面试官的要求,我会非常感激?

【问题讨论】:

  • 不能直接调用构造函数,构造函数也不返回任何东西。我认为这是一个技巧问题,new 运算符计算为指向新对象的指针,但这并不完全相同。虽然,转换运算符和构造函数可用于按值计算实例,但这可能就是它们所指的。
  • 这可能更适合programmers.stackexchange.com
  • 如果可能请不要投反对票帮助我理解它我是新来的PLZ
  • @user3784175:发布有关您不理解的问题的问题不会获得反对票。发布一个我们不完全了解您的问题的问题是什么引起了反对票。请尝试澄清问题。
  • 面试官的问题对我来说毫无意义。 “为什么创建新对象时会创建新对象?”也许存在(人类)语言问题。我会要求澄清的。

标签: c++ object constructor


【解决方案1】:

该面试问题的正确答案是构造函数不返回任何内容。 类的构造函数在其类型的对象被初始化时被调用。那时,用于构造对象的内存区域已经被保留并且地址已知。因此构造函数不需要返回任何东西,除非有错误情况,可以通过异常报告。 构造函数的唯一工作是将有用的值写入该内存区域,并且通常建立由复制和移动操作维护的类的不变量。 为了完成它的工作,构造函数将首先调用其父构造函数,然后再调用其父构造函数,直到继承层次结构的顶部。在多重继承的情况下,父构造函数按照它们的声明顺序被调用。对于虚拟继承,将首先调用虚拟类的构造函数,以确保它在类层次结构中的任何位置都被正确初始化。 一旦父构造函数完成,类的成员就按照声明的顺序进行初始化,最后执行构造函数自己的主体。 破坏以相反的顺序进行,只有完全构建的东西才会被破坏。 一旦对象的构造函数完成,对象就被完全构造了。 因此,如果成员或父构造函数抛出,或者如果您在构造函数的主体中抛出异常,则在此之前成功创建的所有成员和父级都将按照其构造的相反顺序正确销毁。 在使用 new 分配的情况下,对象的内存将被释放并重新抛出异常。

如您所见,构造函数只是初始化您已经知道如何访问它的对象的内存(通常通过变量),因此它永远不会返回任何值。

添加示例:

class T : private parent {
    U member_first;
    V member_second;
};

T foobar() {
    T a{};
    return a;
}

这将使用默认构造函数显式构造一个 T 类型的对象。 定义变量 a 的函数在调用时将在堆栈上保留 sizeof(T) 个字节(假设机器有一个堆栈;))。到目前为止,没有调用任何构造函数。 现在,当调用默认构造函数时,名为 a 的对象的 this 指针被设置为 &a 的值,并执行一个像这样默认定义的构造函数:

T::T() : parent{}, member_first{}, member_second{} {}

我希望这个例子清楚地表明,不是让构造函数返回一些东西,而是隐含地给出了必须初始化的内存区域的地址,类似于返回 void 的函数,它接受一个指针作为参数并更改指向的值。

【讨论】:

    【解决方案2】:

    返回新对象(对创建对象的引用)

    1. 可以复制并分配给其他对象
    2. 可以将类的其他方法应用于创建的对象。

    简而言之,您可以创建用于表达式的临时对象。

    举个例子

    #include <iostream>
    #include <string>
    
    int main() 
    {
        std::cout << std::string( "Hello ").append( "World!" ) << std::endl;
    
        return 0;
    }
    

    构造函数调用是一个表达式,它的类型不同于 void。

    【讨论】:

    • '返回新对象...' 构造函数不返回任何内容,它们正在初始化内存布局并执行其定义中的语句。但他们不返回任何东西。
    • @πάντα ῥεῖ 如果你是对的,那么你就不能处理临时对象,也不能应用其他方法,例如 std::string().append( "Hello" );跨度>
    • @πάνταῥεῖ 我知道,但是当构造函数退出时,运行时返回新创建的实例。所以构造函数没有返回值的原因是因为它不是由你的代码直接调用的,它是由运行时的内存分配和对象初始化代码调用的。它的返回值(如果它在编译成机器代码时实际上有一个)对用户是不透明的——因此,你不能指定它。
    • @user3784175 您不能显式调用构造函数,因此它具有任何返回值没有任何意义。函数签名也表明了这一点。
    • @user3784175 '...运行时返回...'哪个运行时?!?在我的裸机系统的调用堆栈上一切正常。
    猜你喜欢
    • 2021-03-05
    • 2015-10-08
    • 1970-01-01
    • 1970-01-01
    • 2021-11-22
    • 1970-01-01
    • 2017-05-12
    • 2013-11-17
    • 1970-01-01
    相关资源
    最近更新 更多