拷贝构造函数的调用时机:
以下代码段:
class Person
{
public:
Person(int age, std::string name):
m_age(age), m_name(name)
{
qDebug() << "construct!" << this << m_name.c_str() << m_age;
}
Person(const Person& other)
{
this->m_name = other.m_name;
this->m_age = other.m_age;
qDebug() << "copy construct!" << this;
}
Person& operator=(const Person& other)
{
qDebug() << "operator =" << this;
if (&other == this)
return *this;
this->m_name = other.m_name;
this->m_age = other.m_age;
return *this;
}
Person(Person&& other)
{
this->m_name = other.m_name;
this->m_age = other.m_age;
qDebug() << "move construct!" << this;
}
Person &operator=(Person && other)
{
qDebug() << "move operator =" << this;
if (&other == this)
return *this;
this->m_name = other.m_name;
this->m_age = other.m_age;
return *this;
}
~Person()
{
qDebug() << "destruct!" << this;
}
private:
int m_age;
std::string m_name;
};
//Person类作为Test类的成员变量
class Test
{
public:
Test(): p(24, "test")
{
}
~Test()
{
}
Person& GetPerson() // 返回成员变量的引用
{
return p;
}
void onTest()
{
Person result1 = GetPerson();
//这里result1和成员变量p并不是同一个对象
//这里的result1会通过成员变量p调用拷贝构造函数来构造,出了result1的作用域就会析构
Person result2 = result1; //拷贝构造函数, 用来创建 result2 对象
result2 = result1; //赋值运算符, result2 对象是已经存在的
Person& result3 = GetPerson();
//这里result3就是成员变量p; 因为这里使用引用的方式接收返回值;result的生命周期同p一样,
Person result4 = std::move(result1); //移动构造函数
result4 = std::move(result2); //移动赋值运算符
}
private:
Person p; //Person类没有无参构造函数,所以必须在初始化列表进行初始化
Person p2(10, "test"); //报错,C++不允许使用小括号()初始化成员变量
Person p3{10, "test"}; //ok, 大括号统一初始化
Person p4 = Person(10, "test"); //ok, 调用的是构造函数
};
拷贝构造函数的调用时机:
1.以值传递形式传递函数参数
2.函数的返回值是值传递形式,哪怕是函数返回值是引用形式传递,如果不是以引用形式接收,也会进行拷贝(见下例result1
对象)
3.以一个对象来构造另外一个对象
构造函数的调用时机:
1.使用 = 来进行对象的创建时,如以上例子中的 result2
2.在声明时进行初始化,如上p3
、p4
对象