【问题标题】:C++: Is it possible to call an object's function before constructor completes?C++:是否可以在构造函数完成之前调用对象的函数?
【发布时间】:2010-10-14 17:30:45
【问题描述】:

在 C++ 中,是否可以在实例的构造函数完成之前调用实例的函数?

例如如果 A 的构造函数实例化 B 并且 B 的构造函数调用 A 的函数之一。

【问题讨论】:

  • 一切皆有可能。天气它是有效的还是一个好主意取决于你在做什么。有关 A/B 关系以及该方法正在做什么的更多详细信息会很好。 (即一些代码)。
  • @Martin,我故意让这个问题保持一般性。在我的具体情况下,细节是乏味且不重要的。事实上,在阅读完答案后,我决定避免使用它,并将初始化过程与启动业务逻辑的“go”逻辑分离。回想起来,这是一个很好的做法,我会继续采用。
  • 好主意:因为通用问题可以很好地为您提供明确的答案?

标签: c++ function constructor instance


【解决方案1】:

是的,这是可能的。但是,您有责任调用的函数不会尝试访问任何没有调用其构造函数的子对象。通常这是很容易出错的,这就是为什么应该避免它。

【讨论】:

  • 其中包括(但值得强调)的是,您不应该从构造函数中调用虚成员函数,至少不要在不了解会发生什么的情况下调用它。由于任何派生类尚未完全构造,因此在基类构造函数中调用重写的虚函数将调用该函数的基类实现(如果基类函数是纯虚函数,则会出现运行时错误)。所以,最好不要在构造函数中调用 any 虚函数。
  • @Matthew:确实如此。感谢您的宝贵补充!
【解决方案2】:

这很有可能

class A;
class B { 
public:
  B(A* pValue);
};

class A {
public:
  A() {
    B value(this);
  }
  void SomeMethod() {}
};

B::B(A* pValue) {
  pValue->SomeMethod();
}

【讨论】:

    【解决方案3】:

    这是可能的,有时实际上是必要的(尽管它增强了无意中平整城市街区的能力)。例如,在 C++98 中,不是为通用初始化定义人工基类,而是在 C++98 中经常看到由每个构造函数调用的 init 函数完成的。我不是在谈论两阶段构建,这只是 Evil,而是关于分解常见的初始化。

    C++0x 提供构造函数转发,这将有助于缓解问题。

    在实践中它是危险的,必须特别注意初始化的内容和未初始化的内容。对于纯粹的形式,标准中有一些不必要的模糊措辞,可以解释为对象在构造函数成功完成之前并不真正存在。但是,由于这种解释会使它成为 UB 使用例如一个init 函数来分解常见的初始化,这是一种常见的做法,可以忽略它。

    【讨论】:

      【解决方案4】:

      你为什么要这么做?不,它不能完成,因为您需要将对象作为其参数之一。 C++成员函数实现和C函数是不同的东西。

      c++代码

      class foo
      {
          int data;
          void DoSomething()
          {
              data++;
          }
      };
      
      
      int main()
      {
          foo a;              //an object
          a.data = 0;         //set the data member to 0
          a.DoSomething();    //the object is doing something with itself and is using 'data'
      }
      

      这是一个简单的 C 方法。

      typedef void (*pDoSomething) ();
      typedef struct __foo
      {
          int data;
          pDoSomething ds;    //<--pointer to DoSomething function
      }foo;
      
      void DoSomething(foo* this)
      {
          this->data++;   //<-- C++ compiler won't compile this as C++ compiler uses 'this' as one of its keywords.
      }
      
      int main()
      {
          foo a;
          a.ds = DoSomething; // you have to set the function.
          a.data = 0;
          a.ds(&a);       //this is the same as C++ a.DoSomething code above.
      }
      

      最后,你的问题的答案是下面的代码。

      void DoSomething(foo* this);
      int main()
      {
          DoSomething( ?? );  //WHAT!?? We need to pass something here.
      }
      

      看,你需要一个对象来传递给它。答案是否定的。

      【讨论】:

      • 你在 Jared 展示了这一切发生的三个小时后才来,在你的第二句话中你脱口而出说这不可能?!我很惊讶。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-03
      • 1970-01-01
      • 2012-09-28
      • 2021-09-08
      • 1970-01-01
      相关资源
      最近更新 更多