转换构造函数或复制构造函数

conversion constructor or copy constructor

本文关键字:构造函数 复制 转换      更新时间:2023-10-16

我正在努力理解转换构造函数。我正在使用以下代码

class cls 
{
public:
  cls()
  {
      std::cout << "Regular constructor n";     ---> Line A
  }
  cls (int a) //Constructing converter
  {
      std::cout << "Int constructor n";         ---> Line B
  }
  cls (cls& d) //Copy constructor
  {
      std::cout << "Copy constructor n";        ---> Line C
  }
};

int main()
{
    cls d;
    std::cout << "-----------------------n";
    cls e = 15; //int constructor then copy constructor
        return;
}

现在我对语句cls e = 15感到困惑,我的理解是,这个语句应该调用行B(Conversion Cont),然后调用行C(Copy构造函数),但它只调用了行B。我认为cls e = 15等效于cls e = cls(15)。所以我尝试了cls e = cls(15),它也只提供线路B。如果有人能解释一下当我们使用以下时会发生什么,我将不胜感激

cls e = cls(15)//我期望一个转换构造函数后面跟着复制构造函数,但显然我错了。对正在发生的事情的任何解释都将不胜感激

这是由于复制省略编译器优化。在某些情况下,编译器可以省略复制构造函数调用。您所看到的是这种正在进行的优化。您假设呼叫是正确的

  • 转换构造函数,然后是
  • 复制构造函数

但在这种情况下,构造函数会使用返回值优化来消除/删除/优化第二个调用。编译器直接在e中构造对象,而不是创建一个临时对象然后将其复制到e

如果您使用GCC,您可以使用-fno-elide-constructors选项来禁用复制省略,您应该会看到您期望的结果。

编译器似乎在优化代码,而不是调用被称为copy elision 的复制构造函数

请查看此处了解更多详细信息。

基本上,在复制省略中,编译器会优化代码,以省略不必要的中间临时对象。

你说得对,cls e = 15cls e = cls(15)是一样的。这是因为您的cls(int a)没有明确声明。接下来就是编译器拷贝省略优化。