我的情况是似乎没有调用构造函数:
#include <iostream>
using namespace std;
int main ()
{
class yoyo
{
public:
int i;
yoyo()
{
i = 0;
cout << "defaultly initialized to 0" << endl;
}
yoyo (int j) : i(j)
{
cout << "initialized to " << j << endl;
}
};
int i;
yoyo a;
cout << "Hello1, i: " << a.i << endl;
yoyo b(5);
cout << "Hello2, i: " << b.i << endl;
yoyo c = b; /* 1 */
cout << "Hello3, i: " << c.i << endl;
return 0;
}
输出是:
defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
Hello3, i: 5
(注意:Hello2和Hello3之间没有任何内容)
如果我将程序更改为如下所示:
#include <iostream>
using namespace std;
int main ()
{
class yoyo
{
public:
int i;
yoyo()
{
i = 0;
cout << "defaultly initialized to 0" << endl;
}
yoyo (int j) : i(j)
{
cout << "initialized to " << j << endl;
}
};
int i;
yoyo a;
cout << "Hello1, i: " << a.i << endl;
yoyo b(5);
cout << "Hello2, i: " << b.i << endl;
yoyo c; c = b; /* 1 */
cout << "Hello3, i: " << c.i << endl;
return 0;
}
(唯一的区别在于他的行标有/ * 1 * /)
现在的输出是:
defaultly initialized to 0
Hello1, i: 0
initialized to 5
Hello2, i: 5
defaultly initialized to 0
Hello3, i: 5
现在Hello2和Hello3之间存在构造函数调用。我的问题是,为什么在第一种情况下没有(可见)构造函数调用?
答案 0 :(得分:16)
在
的情况下yoyo c = b;
这是被调用的copy constructor。
在
的情况下yoyo c; c = b;
它是被调用的copy assignment运算符。
如果您不提供其中任何一个,编译器将为您生成默认版本。
如果您想创建自己的复制构造函数,它可能如下所示:
yoyo(const yoyo& other)
: i(other.i)
{ std::cout << "copy constructor initialized\n"; }
复制赋值运算符如下所示:
yoyo& operator=(const yoyo& other)
{
i = other.i;
return *this;
}
当然,他们都在里面定义了类定义。
答案 1 :(得分:7)
在第一种情况下:
yoyo c = b;
调用copy constructor
,编译器在这种情况下隐式生成了{{1}}。
答案 2 :(得分:3)
yoyo c = b;
这称为复制初始化;将调用编译器生成的复制构造函数,并使用该副本初始化c
。此外,将调用c
的默认构造函数。
c = b;
这里,这不是初始化,这是赋值。将在该行上调用编译器生成的赋值运算符。
答案 3 :(得分:1)
在你的代码中,
yoyo c=b
将调用复制构造函数。如果要查看它被调用,则必须明确定义它。
例如:
yoyo(const yoyo& obj)
{
this->i=obj.i; cout<<"copy constructor"<<endl;
}
在第二种情况下,它将调用构造函数,然后调用赋值运算符
yoyo c; //constructor
c = b; //assignment operator for which only copying occurs
你可以重载赋值运算符,如下所示
yoyo& operator=(yoyo& obj)
{
i = obj.i;
cout << "assignment operator" << endl;
}