【问题标题】:Delayed constructor in C++C ++中的延迟构造函数
【发布时间】:2009-05-06 14:35:40
【问题描述】:

我一直在查看一些看起来像这样的代码:

class A; // defined somewhere else, has both default constructor and A(int _int) defined
class B
{
public:
    B(); // empty
    A a;
};

int main()
{
     B* b;
     b = new B();
     b->a(myInt); // here, calling the A(int _int) constructor,
     //but default constructor should already have been called
}

这行得通吗?在调用默认构造函数后调用特定构造函数?

【问题讨论】:

    标签: c++ constructor default


    【解决方案1】:

    该代码没有调用 a 的构造函数。它调用A::operator()(int)

    但是如果你在一个已经被构造的对象上显式地调用了一个构造函数,你就进入了未定义的行为领域。它在实践中似乎可行,但不能保证它会达到您的预期。

    【讨论】:

    • 如果声明了该函数,它只调用“A::operator()(int)”?您能够确定该函数已被声明,这给我留下了深刻的印象!
    • @Richard:我不确定你在说什么。如果未声明该函数,则代码将无法编译。所以假设代码确实编译,这意味着必须定义操作符。没有歧义。使用的语法从不调用构造函数,如果那是你得到的。为此,您必须改为编写 b->a::A(myInt) 。 Rich 的问题中显示的语法only 可以调用 operator()。
    • "write b->a::A(myInt)" 这是合法的 C++ 吗?当然不能在我的编译器上编译。我在这里可能错了,但据我所知,没有办法调用对象的构造函数,除非它被创建或通过放置 new。任何设法显式调用类的构造函数的东西实际上都会先创建一个临时对象。
    • 我什么也没说。我知道你不能像这样调用构造函数,我错过了关于他审查代码的一点,所以是的 - 正如你所说,如果代码编译类必须声明一个仿函数。
    • Ari:你说得对,我搞砸了语法。它应该是“b->a.A::A(myInt)”。 (即使这样显然也很少有效或有意义。)
    【解决方案2】:

    您可以在 B 类中创建另一个构造函数

    B(int _int):a(_int) {}

    在这种情况下,当你写 b = 新 B(myInt);

    以上代码不会耽误你A类的构造函数代码。

    你不需要调用 b->a(myInt)

    【讨论】:

    • 这不是合法的 C++。你应该从你的答案中删除“是的,它会起作用”,否则你可能会被打分。
    • 我在这条评论中没有看到任何非法的 C++
    • 之前我说过问题中的代码会运行。但在理查德科登纠正我之后,我编辑了我的回复。现在好了。因此,您不会看到任何不正确的代码。
    【解决方案3】:

    这不是调用构造函数,this 的答案涵盖了对正在发生的事情的唯一可能解释。

    在现有对象上调用构造函数的唯一标准方法是使用placement new,(在前一个实例被破坏之后):

    void foo (A * a) {
      a->~A ();           // Destroy previous instance
      new (a) A(myInt);   // Construct new object in same location
    } 
    

    【讨论】:

    • 放置 new 可能会很危险,以防构造函数有副作用(例如,计算活动对象的数量)。最好将其保留为替换默认内存管理系统的预期目的。
    • @Ari。当然。但这是在已构建的对象上调用构造函数的唯一方法(如果您打算这样做)。
    • 其实你得先解构对象:b->a.~A();在安置新的之前。新位置仅适用于原始对齐的内存。
    【解决方案4】:

    您应该只在 B() 构造函数中调用 A(int) 构造函数,或者创建一个也调用 A(int) 的 B(int) 构造函数。

    最佳实践是两者都有,默认一个为 A 设置默认 int,而 B(int) 一个用于初始化 A(int)。

    【讨论】:

      猜你喜欢
      • 2013-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多