Language agnostic 初始化或构造

Language agnostic 初始化或构造,language-agnostic,constructor,Language Agnostic,Constructor,我正在查看一些代码,我看到了很多这样的情况: class Foo { public: Foo() { // 'nuffin } void init() { // actual construction code } } ; 我能看到的唯一优势是,如果您创建一个Foo而不使用指针,并且希望将其构造代码推迟到以后,那么您就可以了 这是个好主意还是个坏主意?我不喜欢。在我看来,在构造之后,一个对象应该是。。。好。。。构建。相反,该代码使其处于无效状态,这几乎

我正在查看一些代码,我看到了很多这样的情况:

class Foo
{
public:
  Foo()
  {
    // 'nuffin
  }

  void init()
  {
    // actual construction code
  }
} ;
我能看到的唯一优势是,如果您创建一个Foo而不使用指针,并且希望将其构造代码推迟到以后,那么您就可以了


这是个好主意还是个坏主意?我不喜欢。在我看来,在构造之后,一个对象应该是。。。好。。。构建。相反,该代码使其处于无效状态,这几乎从来都不是一件好事


插入一个黄鼠狼词来解释不可预见的情况。

一般来说,源代码应该尽可能简单,并且您的示例没有上下文,因此它比必要的更复杂,因此您的示例是一个坏主意


但是,可能存在一些语义上下文,在这些上下文中,能够交付未初始化的对象可能是有意义的——例如,如果上下文要求容器包含对象,但由于初始化速度慢和/或可能不需要对象,您不想在以后才对其进行初始化。在这些情况下,额外的复杂性可能会使其他事情变得更简单。

我认为构造函数基本上也应该完成init()部分。除非对象已完全构造,否则不应使用它


此外,在构造函数中初始化允许您使用RAII。RAII的基本点是用本地对象表示资源,在构造函数中初始化,以便本地对象的析构函数释放资源。这样,程序员就不会忘记释放资源。

如果类上存在依赖于处于某种初始化状态的对象的方法,则两阶段构造通常被认为是一个坏主意。通常,我更喜欢保证对象处于良好状态的构造函数,或者如果无法做到这一点(可能是因为构造函数的某些参数无效),则抛出异常,这样就不会有类实例处于不良状态


要求对象的使用者记住调用
init()
是个坏主意,因为它们不会调用。

这可能适用的一种情况是,当“Foo”是另一个类的属性,并且在父类完成之前无法完全构造它时。只有这样,“Foo”才能被“填充”

不同之处在于,初始化发生在调用超类的构造函数之后,但在本地类构造函数中执行任何代码之前。因此,它确实取决于您的需要。

尽管它不能被视为构建对象的正常或首选方法,但在某些情况下,这可能是一种可行的方法。例如,您可能只需要构造一个对象来表示它的存在(在某些列表中,计数确实很重要等等),但只有在第一次使用这个特定对象时才需要初始化它,因为初始化整个对象集合将花费很多时间


在这种情况下,最好通过包含类似
isInitialized()
的方法来公开对象可能未初始化的事实。同样,通过这种方式,您可以将初始化转移到另一个线程,以避免阻塞应用程序的主线程。

在某些语言(读:C++)中,您不能从另一个构造函数调用构造函数,因此,如果您想要多个构造函数的公共部分,则需要将其放在一个单独的方法中,我已经看到了init()的名称用于那个。但这不是您所说的吗?

如果要实例化基于数据库调用的对象,我将使用constructor和init。因此,如果我需要一个空对象,以便填充它,然后将其保存到数据库中,那么我不使用参数进行构造,也不调用init()。然而,如果我需要从db中检索对象成员,我将
构造($param)
并将$param传递给
init($param)
,一般来说,我同意这是需要避免的。但到目前为止,没有一个答案能够解决初始化可能失败的问题。构造函数不能失败,因此如果构造函数分配内存、打开文件或执行任何其他可能失败的操作,则需要一种方法告诉调用方发生了错误。如果在构造函数中进行初始化,则需要有一个标志来指示初始化是否成功,然后确保调用方检查该标志


如果您有一个单独的init()例程,必须在其他任何操作开始之前调用该例程,那么在创建对象后,调用方更有可能检查返回代码,而不是调用
didInitializationSucceed()
方法。

我有点困惑,您将问题定位为语言无关(而不提供目标语言),而问题是关于检查代码。我认为审查代码将与被审查的语言高度相关。如果不是,为什么我们不使用相同的语言呢?;-)我对你的问题进行了编辑,使代码的语法着色。不要使用PRE,而是在每行代码前面放8个空格。@KLE-现在每行代码前面都有一堆空格。您应该只需要4个空格就可以获得语法着色。这里发生了一些有趣的事情。+1:即使在可以调用另一个构造函数(read:Java)的语言中,也可能存在一些约束(比如必须在另一个构造函数体中首先调用它),您可能需要解决这些约束。但是,在这种情况下,我会将In()方法作为私有实现。在C++中,构造函数将抛出异常(正常情况)或返回0(如果用(NoWORT)构造)。它不会留下一个部分构造的对象。在什么语言中会发生这种情况?如果使用此方法构造对象,则运行任何超类构造函数,运行类构造函数,然后调用init()。