构造函数被多次调用

Abh*_*rma 2 c++

我写了下面的c ++代码试图理解c ++中的copy elision.

#include <iostream>
using namespace std;

class B
{
  public:  
  B(int x  ) //default constructor
  {
    cout << "Constructor called" << endl;
  }    

  B(const B &b)  //copy constructor
  {
     cout << "Copy constructor called" << endl;
  } 
};

int main()
{ 

  B ob =5; 
  ob=6;
  ob=7;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

Constructor called
Constructor called
Constructor called
Run Code Online (Sandbox Code Playgroud)

我无法理解为什么构造函数被调用三次,每次赋值给对象ob.

Jam*_*son 5

B ob = 5;

这使用给定的构造函数.

OB = 6;

这使用给定的构造函数,因为没有B& operator=(int)函数,6必须转换为类型B.执行此操作的一条路径是临时构造a B并在赋值中使用它.

OB = 7;

与上述答案相同.

我无法理解为什么每次赋值都会对构造函数进行三次调用

如上所述,您没有B& operator=(int)函数,但编译器很乐意自动B& operator=(const B&);为您提供复制赋值运算符(即).正在调用编译器生成的赋值运算符,它采用一种类型,所有类型都可以转换为一种类型(通过您提供的构造函数).BintB

注意:您可以通过使用explicit(即explicit B(int x);)禁用隐式转换,我建议使用explicit除了需要隐式转换时.

例

#include <iostream>

class B
{
public:
    B(int x) { std::cout << "B ctor\n"; }

    B(const B& b) { std::cout << B copy ctor\n"; }
};

B createB()
{
    B b = 5;
    return b;
}

int main()
{
    B b = createB();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

示例输出

注意:使用Visual Studio 2013编译(发布)

B ctor
Run Code Online (Sandbox Code Playgroud)

这表明复制构造函数被省略了(即,函数中的B实例createB被触发但没有其他构造函数).

  • 您可以通过使用`explicit`(例如,`explicit B(int x);`)来阻止隐式转换,这会导致`B b = 5`产生编译错误.除非你想要隐式转换,否则我建议使用`explicit`. (2认同)