提问人:Luckk 提问时间:12/13/2022 更新时间:12/13/2022 访问量:34
将 -fno-elide-constructors 标志传递给编译器时的副本数
Number of copies when -fno-elide-constructors flag is passed to the compiler
问:
请考虑以下类:
struct IntPointerWrapper
{
int* data_pointer;
IntPointerWrapper() : data_pointer(new int())
{
std::cout << "IntPointerWrapper()" << std::endl;
}
IntPointerWrapper(const IntPointerWrapper& other) : data_pointer(new int())
{
std::cout << "IntPointerWrapper(const IntPointerWrapper& other)" << std::endl;
*data_pointer = *other.data_pointer;
}
IntPointerWrapper& operator=(const IntPointerWrapper& other)
{
std::cout << "operator=(const IntPointerWrapper& other)" << std::endl;
*data_pointer = *other.data_pointer;
return *this;
}
~IntPointerWrapper()
{
std::cout << "~IntPointerWrapper() " << std::endl;
delete data_pointer;
}
};
还有一个简单的工厂方法
IntPointerWrapper bar()
{
IntPointerWrapper q;
return q;
}
int main()
{
IntPointerWrapper m = bar();
}
我想使用禁用的复制省略进行编译,以查看复制构造函数被调用了多少次。
我得到这个输出:
IntPointerWrapper()
IntPointerWrapper(const IntPointerWrapper& other)
~IntPointerWrapper()
IntPointerWrapper(const IntPointerWrapper& other)
~IntPointerWrapper()
~IntPointerWrapper()
所以复制构造函数被调用了两次,但我真的不明白为什么。在运行这个实验之前,我敢打赌一个电话就足够了。
我想知道这 2 个副本而不是单个副本背后是否有任何动机,或者它只是特定于实现的东西。
我尝试了 Clang、GCC 和 MSVC,得到了相同的结果。
答:
3赞
NathanOliver
12/13/2022
#1
跟
IntPointerWrapper bar()
{
IntPointerWrapper q;
return q;
}
您可以复制到函数的返回对象中。这是你的第一个副本。然后你有q
IntPointerWrapper m = bar();
它将返回的值从 中复制到 ,因此这是您的第二个复制操作。bar()
m
应该注意的是,这两个副本只发生在 C++17 之前。从 C++17 开始,我们保证了复制省略,这摆脱了发生在 并且只有返回对象的副本的副本。你可以在这个实时示例中看到这种差异IntPointerWrapper m = bar();
评论