【问题标题】:Understanding C++ reconstruct syntax了解 C++ 重构语法
【发布时间】:2012-07-07 21:00:34
【问题描述】:

对象创建后可以再次调用它的构造函数吗?

#include <iostream>

struct A
{
    A ( ) { std::cout << "A::A" << std::endl; }
    ~A ( ) { std::cout << "A::~A" << std::endl; }
};

int main( )
{
    A a;
    a.~A();    // OK
    a.A::A();  // OK in Visual Studio 2005, 2008, 2010

    return 0;
}

【问题讨论】:

  • 最后一次通话怎么会没问题? oO
  • 在每个人开始将他们的赞成票转换为反对票之前。如果没有最后一次通话,问题仍然存在。
  • @ThomasMcLeod 不在 g++ 4.6.3 上,它没有。你用的是哪个编译器?
  • @ThomasMcLeod:不,这不是共识,因为我们还没有检查所有编译器。共识似乎是它不应该任何标准兼容的编译器上工作。然而,非正式地,我们都同意 VC 很可能是此类错误的候选者。
  • a.A() 中,A 将结构类型命名为A。如果你说a.A::A(),最后一个A 命名构造函数(这是根据标准规则)。然而,标准禁止直接调用构造函数(实际上除了一些关于构造函数的类似声明的事情之外,几乎所有事情都是不允许的)。

标签: c++ syntax constructor scope language-lawyer


【解决方案1】:

你不应该像这样调用构造函数,作为成员函数调用。原因是(n3242, 12.1/2):

构造函数用于初始化其类类型的对象。因为构造函数没有名字,所以它们是 在名称查找期间从未找到;但是使用功能符号(5.2.3)的显式类型转换 将导致调用构造函数来初始化对象。

如果你真的想在应该是对象的东西上调用构造函数——除非在非常特殊的情况下你不应该这样做——你可以使用调用构造函数的放置 new:

new (&a) A();

【讨论】:

  • 别忘了先销毁对象!
  • “在名称查找过程中永远找不到它们”,这是不正确的。如果在名称查找过程中永远找不到它们,那么您将永远无法在类外定义构造函数、与构造函数交朋友或继承构造函数。它们没有名称,但这暗示在名称查找过程中永远找不到它们。通过使用注入的类名并使其引用构造函数作为名称查找结果来找到构造函数。
  • @JohannesSchaub-litb:这很有趣,但也许你应该写信给委员会,因为这是对标准的引用。您说得对,3.4.3.1/2 在某些情况下允许在名称查找中找到构造函数;幸运的是,它不允许在成员函数调用的 id-expression 中使用它。
  • 叹息。 是什么让 C++ 引用该标准的任何答案比其他所有答案都更受欢迎? +1 也来自我。 :)
【解决方案2】:

好吧,a.A() 无法编译,因为您根本无法在 C++ 中调用构造函数。 (您可以通过多种方式间接调用它。)出于同样的原因,我认为a.A::A() 不应该 编译。

【讨论】:

  • 确实:构造函数没有名字。它永远不会在名称查找中找到,因此无法直接调用。
  • @GManNickG 他们没有名字,但可以在名字查找中找到。请参阅我对 jpalecek 答案的评论。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-12
  • 2021-11-22
  • 2015-11-08
  • 2017-03-30
  • 1970-01-01
  • 1970-01-01
  • 2015-05-03
相关资源
最近更新 更多