【问题标题】:C++ implicit conversion constructor callC++隐式转换构造函数调用
【发布时间】:2013-11-02 22:46:48
【问题描述】:

为什么 gcc 需要复制构造函数来调用隐式转换构造函数?

class X
{
public:
        X(int q) {}

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

        X(const X&) = delete;
};

X x = 1; // gives error: use of deleted function ‘X::X(const X&)’

这里更有趣的是,即使我编写了复制构造函数,它也不会被调用。析构函数只调用一次,所以如下代码

class X
{
public:
    X(int q) {}

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

    X(const X&)
    {
        std::cout << "copy ctor" << std::endl;
    }
};

int main()
{
    X x = 1;
}

打印~X()

这是错误吗?有什么解决办法吗?

我本地 PC 上的 gcc 版本是 4.6.3,这在另一个 gcc 版本(在线)上也是如此

http://ideone.com/ustDRj

【问题讨论】:

  • 这不是bug,它被称为copy elision。在某些情况下,允许编译器省略副本。它仍然要求复制构造函数可用。

标签: c++ gcc constructor copy-constructor implicit-conversion


【解决方案1】:

您正在尝试在此处为调用复制构造函数的类对象初始化一个值。

int main()
{
    X x = 1; 
}

把代码改成

X x(1);

【讨论】:

    【解决方案2】:

    X x = 1;复制初始化的语法。 如果初始化器不是X 类型(如这里),这在语义上等价于:

    X x(X(1));
    

    也就是说,它从参数1 构造一个X 实例,然后从该实例复制初始化x

    就像任何其他副本初始化一样,副本可以被省略。这可能发生在您的情况下,因此实际上并未调用复制构造函数。尽管如此,(再次,就像任何其他复制省略一样),它必须是可用的。

    【讨论】:

    • 好的,那为什么我公开复制构造函数不调用呢?
    • @axe 因为复制省略。
    • 谢谢。但无论如何,这很奇怪。它可以直接调用像 X x(1) 这样的构造函数。我看不出在这里进行复制构造的原因。
    • @axe 是因为T t(x)T t = x;的语义不同。查看更多关于 here.
    • 也可以使用 C++11 统一初始化语法 X x{1};
    猜你喜欢
    • 2014-02-24
    • 1970-01-01
    • 2011-09-18
    • 2014-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多