c++ - 直接和复制构造函数

标签 c++ class constructor initialization

class UnusualClass
{
    int a;
    public:
        UnusualClass(int a){std::cout<<"Direct initialization"<<std::endl;}
        UnusualClass(const UnusualClass &n){std::cout<<"Copy initialization"; }
};


int main ()
{
    UnusualClass k1(5);    //Direct initialization
    UnusualClass k2=56;   //Copy initialization
    return 0;
}

为什么编译器会打印两次“Direct initialization”?我做了一些研究,发现我可能会得到复制构造函数省略。 这两种情况有可能得到两种不同的结果吗? 此外,当我使用 UnusualClass(const UnusualClass &n)=delete 时,我收到一条错误消息,提示 use of deleted function 'UnusualClass::UnusualClass(const UnusualClass&)。如果无论如何都跳过此构造函数,为什么我会收到此错误?

我知道我可以通过使用两个构造函数 UnusualClass(int a);UnusualClass(double b); 来获得两种不同的结果,但这个技巧看起来并不完全对。

最佳答案

Copy initialization并不意味着必须调用复制构造函数。

If T is a class type, and the cv-unqualified version of the type of other is not T or derived from T, or if T is non-class type, but the type of other is a class type, user-defined conversion sequences that can convert from the type of other to T (or to a type derived from T if T is a class type and a conversion function is available) are examined and the best one is selected through overload resolution. The result of the conversion, which is a prvalue temporary (until C++17) prvalue expression (since C++17) if a converting constructor was used, is then used to direct-initialize the object. The last step is usually optimized out and the result of the conversion is constructed directly in the memory allocated for the target object, but the appropriate constructor (move or copy) is required to be accessible even though it's not used. (until C++17)

在这个拷贝初始化的过程中(即UnusualClass k2=56;),UnusualClass::UnusualClass(int)会被选择用于转换intUnusualClass,所以它首先被调用。转换后的UnusualClass用于直接初始化对象k2,所以概念上需要拷贝构造函数。在 C++17 之前甚至 copy elision碰巧复制构造函数必须是可访问的,这就是为什么当你让它 delete 你编译失败的原因。自 C++17 copy elision得到保证,并且复制构造函数不需要再次访问。

关于c++ - 直接和复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50434070/

相关文章:

javascript - 如何从 javascript 类方法返回一个值?

c++ - 类型转换、显式构造函数等

c++ - Xcode 链接器错误 Cocos2d-x Box2D CContactListener 构造函数未定义

Typescript构造函数,这两种构造对象的方法是等价的吗?

c# 到 c++ 字典到 unordered_map 结果

c++ - 如何获取非常大的十六进制字符串并格式化输出

c++ - 如何在控制台 C++ 应用程序中使用 lib 文件

c++ - 在 Dev C++、VS 中使用 GetOpenFileName

jquery,按类查找下一个元素

excel - VBA 类对象中是否必须有重复值?