如何";默认构造函数";在C++; 最近我遇到了一个问题,因为我是一个自学的C++程序员,我真的很想知道现实世界中的专业人员如何解决它。

如何";默认构造函数";在C++; 最近我遇到了一个问题,因为我是一个自学的C++程序员,我真的很想知道现实世界中的专业人员如何解决它。,c++,default-constructor,C++,Default Constructor,为所有类编写默认构造函数是个好主意吗?如果您的类没有默认构造函数,STL的某些部分难道不起作用吗 如果是这样的话,那么如何编写一个默认的构造函数来做一些有意义的事情呢?也就是说,如果没有合理的默认值,我如何为我的私有成员分配默认值?我只能想到两种解决办法: 为每个成员使用指针(或唯一的_ptr),这样,nullptr意味着该字段未初始化 或 添加额外的字段/逻辑/方法来检查字段是否已初始化,并依赖于此(类似于unique_ptr的“重置”方法) 在现实世界中,人们如何解决这样的问题 为所有类编写

为所有类编写默认构造函数是个好主意吗?如果您的类没有默认构造函数,STL的某些部分难道不起作用吗

如果是这样的话,那么如何编写一个默认的构造函数来做一些有意义的事情呢?也就是说,如果没有合理的默认值,我如何为我的私有成员分配默认值?我只能想到两种解决办法:

  • 为每个成员使用指针(或唯一的_ptr),这样,nullptr意味着该字段未初始化
  • 添加额外的字段/逻辑/方法来检查字段是否已初始化,并依赖于此(类似于unique_ptr的“重置”方法)
  • 在现实世界中,人们如何解决这样的问题

    为所有类编写默认构造函数是个好主意吗

    不。有时,为对象设置默认值是没有意义的

    如果您的类没有默认构造函数,STL的某些部分难道不起作用吗


    有些部分需要默认的可构造对象。还有一些方法可以绕过它(重载使用对象而不是默认构造的对象)。

    如果您的数据类型使用默认构造函数没有意义,那么不要编写默认构造函数

    (STL早已过时,但我想你指的是标准库。)大多数标准库容器工作良好,即使包含的类型没有默认构造函数。一些值得注意的问题:

    • std::vector::resize(n)
      要求
      T
      具有默认构造函数。但是如果没有,您可以使用
      擦除
      插入

    • std::map::operator[]
      std::unordered\u map::operator[]
      要求
      V
      具有默认构造函数。但是如果没有,您可以使用
      find
      insert

    为所有类编写默认构造函数是个好主意吗

    否。如果您的类型没有合理的“默认值”,则不应编写默认构造函数。这样做违反了最小意外原则

    也就是说,许多类型确实有一个合理的默认值

    • 数字零(更一般地说:中性元素)
    • 空字符串
    • 空名单
    • 一个0×0矩阵
    • 时区UTC±00:00
    对于这种类型,您确实应该定义一个默认构造函数

    其他类型没有自然默认值,但具有“空”状态,可以通过执行某些操作来达到该状态。默认构造这样一个对象使其具有该状态是明智的

    • 与任何源/接收器断开连接的I/O流,每次操作都失败(可以通过到达文件末尾或遇到I/O错误来访问)
    • 没有锁的锁防护装置(可以通过释放锁来达到)
    • 不拥有对象的智能指针(可以通过释放托管对象来访问)
    对于这些类型,是否定义默认构造函数是一种权衡。这样做没有坏处,但会使你的类型稍微复杂一些。如果它是在库中找到的公共类型,那么它可能值得麻烦。如果无论如何都要实现移动构造函数(和赋值操作符),那么同样可以定义默认构造函数来构造对象,使其处于离开对象时可以达到的状态

    对于其他类型,您无法定义合理的默认值

    • 一周中的一天
    • 婴儿的名字
    不要为这些类型发明一个人工的“null”状态,只是为了使它们可以默认构造。这样做会使代码复杂化,并迫使您在没有人工状态的情况下尽可能提供不太有用的类不变量。如果有人真的需要这个额外的状态,他们可以很容易地使用一个,但反过来是不可能的

    如果您的类没有默认构造函数,STL的某些部分难道不起作用吗


    std::vector::resize
    可能是最突出的例子。但是不要担心这些。如果您的类型没有合理的默认值,那么执行该操作也没有意义。这不是你这类人的错。这是您试图建模的概念的本质所固有的。

    专业人士阅读书籍,您也应该:。总是存在一个重载
    std::vector::resize(n,value)
    ,它不需要默认可构造的T。谢谢!这真的很有帮助!我以前对std::map有过一些问题:)@melak47:虽然这在形式上是正确的,但它并不是很有用。如果在默认构造函数中没有要实现的有用的默认操作,则不太可能有任何可用的默认状态作为
    值传递。最好改用
    reserve()
    ,一次添加一个非默认构造元素。