【问题标题】:Why we do need constructors? [closed]为什么我们需要构造函数? [关闭]
【发布时间】:2012-01-06 04:33:15
【问题描述】:

今天我的朋友问我,为什么我们真的需要 C++ 中的构造函数? 我们可以在结构语言中做同样的事情。 构造函数的特点是什么,告诉我构造函数的需要,以便我应该在我的 C++ 程序中使用它。 请帮帮我,给我一些例子,以便我能够消除他的疑问。

【问题讨论】:

  • 为什么人们使用承包商为他们建造房屋? ...因为这比自己做更容易。
  • 您可能会建议您的朋友尝试在汇编中编写所有内容。
  • @Marc B,您提到构造函数在创建对象时默认为类中的所有数据成员变量分配内存?默认构造函数主体包含什么?编译器是否向用户定义的构造函数注入任何隐藏代码?如果是,它看起来如何?请解释一下。

标签: c++ visual-c++


【解决方案1】:

你不需要需要构造函数,就像你不需要需要流行语言的大多数特性一样。

构造函数的存在使错误的事情变得更加困难。在这种情况下,使用尚未初始化的数据。

【讨论】:

  • 同意。尽管几十年来它已经添加了自己的完全成熟的功能,但值得记住的是,C++ 最初是作为 C 语言的预处理器。构造函数是一个 init 函数,就像你用 C 编写的任何好的 init 函数一样,但它们首先类语言支持,因此用户要记住的事情少了一件,因此比使用仍然可能的两步初始化模式更安全。这与 C++ 致力于使用户生成的类型的行为方式与内置类型相同的原因相同。不一致的地方越少,就越容易学习和使用。
  • @Drew Dormann,你所说的“错误的事情”是什么意思?请解释一下。
  • @sree 在这种情况下,“错误的事情”是指使用尚未初始化的数据。
  • @Drew Dormann,请为“错误的事情”提供更多示例。
  • @Svalbard: "默认构造函数不初始化对象" - 它和任何构造函数一样多,我的意思是它将执行相同的默认初始化基和成员,而不是初始化在类定义中显式分配给的内置类型的数据成员,也不初始化默认构造函数初始化列表。基本上,不提供自定义默认构造函数是程序员表示上述对象的充分初始化的方式。
【解决方案2】:

一个病态的答案是构造函数不会改变语言的图灵完备性,因此,严格来说,你不需要它们,因为你不需要语言的许多特性。但这是正式的而不是实际的。你会因为只考虑理论而在晚上感觉不到温暖而被原谅。

为什么构造函数有用的一个很好的实际例子是考虑 RAII 模式。通过使用构造函数,您可以将初始化和获取都很好地封装在具有破坏的相同位置。没有构造函数的 C 以程序员忘记该过程中的步骤而闻名。

【讨论】:

    【解决方案3】:

    正如其他人已经回答的那样,您使用构造函数的方式与在过程语言中使用 init 函数的方式相同,但是由于有了构造函数,程序员不会忘记调用 init 函数 - 编译器会这样做为了他。除了自动调用它之外,这带来的另一个好处是优雅地解决了继承初始化问题:如果类 A 扩展类 B 扩展类 C,则可以保证所有将调用三个构造函数(用于 A、B 和 C 类),并且它们将以正确的顺序调用(C 类,然后 B 类,然后 A 类),这样每个构造函数就可以使用超类中的所有数据(因为它已经被初始化了)。对于没有构造函数的语言,程序员需要处理所有这些记录。

    【讨论】:

      【解决方案4】:

      这正是面向对象语言的工作方式。在 C 中,您将使用 malloc 分配内存,然后以某种方式初始化该内存。在 C++ 中,构造函数做了两件事。通过将这两件事放在一起,这使得开发人员更难分配内存和失败/忘记初始化它。

      【讨论】:

        【解决方案5】:

        因为有些对象需要数据来初始化。使用构造函数,您可以确保在编译时对象获取数据。否则编译器会抛出错误。

        【讨论】:

          【解决方案6】:

          不可变对象。

          当您使用并行或并发编程时,共享无法更改的对象要容易得多。您不必担心竞争条件、锁等。但在大多数 OOP 语言中创建不可变对象的唯一方法是通过构造函数。您不能在对象上设置属性,因为根据定义,所有属性都是只读的。

          【讨论】:

          • 但是如果你的对象是不可变的,那它为什么是一个对象呢? (这个问题是关于 C++ 的。)
          • 您可能仍然需要功能并且该功能可能是多态的。例如,WinRT 中有只读列表接口,您可能希望在 C++ 中实现。
          【解决方案7】:

          在过程语言中,您还需要将变量初始化为明确定义的值。通常带有某种Init 功能。构造函数是一种确保在创建对象时将其初始化为有效状态的方法。

          在 .net 中,您可以绕过构造函数(使用特权代码),您将获得一个字段初始化为 0 的对象。

          【讨论】:

            猜你喜欢
            • 2011-02-04
            • 2016-09-24
            • 2023-04-09
            • 2015-02-24
            • 2021-10-15
            • 2015-01-27
            • 2011-05-27
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多