通过示例理解复制构造函数和赋值操作符
Understanding copy constructors and assignment operators with an example
我最近一直在阅读《c++ with Qt 4设计模式介绍》这本书,我对下面的例子感到困惑(代码来自书中,我自己做了一点修改):
"fraction.h"class Fraction
{
public:
Fraction(int n, int d): m_Numer(n), m_Denom(d) {
++ctors;
}
Fraction(const Fraction& other)
: m_Numer(other.m_Numer), m_Denom(other.m_Denom) {
++copies;
}
Fraction& operator = (const Fraction& other) {
m_Numer = other.m_Numer;
m_Denom = other.m_Denom;
++assigns;
return *this;
}
Fraction multiply(Fraction f2) {
return Fraction (m_Numer*f2.m_Numer, m_Denom*f2.m_Denom);
}
static void report();
private:
int m_Numer, m_Denom;
static int assigns;
static int copies;
static int ctors;
};
"main.cpp"#include <iostream>
#include "fraction.h"
using namespace std;
int Fraction::assigns = 0;
int Fraction::copies = 0;
int Fraction::ctors = 0;
void Fraction::report()
{
cout<<"[assigns: "<<assigns<<", copies: "<<copies<<", ctors: "<<ctors<<"]nn";
}
int main()
{
Fraction twothirds(2, 3); // It calls a constructor
Fraction threequarters(3, 4); // It calls a constructor
Fraction acopy(twothirds); // It calls a copy constructor
Fraction f4 = threequarters;
// [Question A]: The book says it's using a copy constructor
// but I don't see how. Isn't it an assignment?
cout<<"after declarationsn";
Fraction::report(); //output: [assogns: 0, copies: 2, ctors: 2]
f4 = twothirds; // It's an assignment using the assignment operator
cout<<"before multiplyn";
Fraction::report(); //output: [assogns: 1, copies: 2, ctors: 2]
f4 = twothirds.multiply(threequarters);
cout<<"after multiplyn";
Fraction::report(); //output: [assogns: 2, copies: 3, ctors: 3]
// [Question B]: How does the frunction "multiply" creates three Fraction objects?
return 0;
}
根据我在main.cpp
留下的评论,我有两个问题。
[问题A]:为什么Fraction f4 = threequarters
使用复制构造函数而不是赋值?
[问题B]:函数"乘法"如何创建三个Fraction对象?
特别是问题B,我想不出这三个东西是从哪里来的。
请帮助我理解这些概念。
问题A:为什么Fraction f4 = three/quarters使用复制构造函数而不是赋值?
答案A:这是c++语言的定义。如果你用了
Fraction f4;
f4 = threequarters;
则第二行使用赋值操作符
问题B:函数"乘法"如何创建三个Fraction对象?
答案B:
当你调用multiply
时,参数f2
是通过复制构造创建的。
return Fraction (m_Numer*f2.m_Numer, m_Denom*f2.m_Denom);
使用正则构造函数构造对象。
f4 = twothirds.multiply(threequarters);
将multiply
构造的对象赋值给f4
。
问题A:因为在一行Fraction f4 = threquarters中,f4还不存在,所以调用复制构造函数来创建一个" threquarters "的副本。操作符=只在对象已经存在时调用。F4 =三分之二)
问题B: Fraction multiply(Fraction f2),当执行twothirths .multiply(threquarters)时,函数调用参数是"按值传递"的(即。将副本传递给函数)。所以在这个例子中,复制了一个"threequarters"并传递给"multiply"。然后在该函数内部通过调用构造函数显式地创建了一个Fraction。最后,您将其作为Fraction返回,这意味着返回了它的副本。所以整个函数调用进行了1次复制构造函数调用来传递它,1次构造函数调用来创建Fraction, 1次复制构造函数调用来返回Fraction,总共3次
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- 使用仅使用一次的变量调用的复制构造函数.这可能是通过调用move构造函数进行编译器优化的情况吗
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 复制构造函数、赋值运算符C++
- std::ofstream 作为类成员删除复制构造函数?
- 复制构造函数C++无法正确复制指针
- 关于复制构造函数的一个棘手问题
- 为什么调用复制构造函数而不是移动构造函数?
- 填充上编译器生成的复制构造函数之间的不一致
- C++ 对象指针数组的复制构造函数
- C++ 基本 CTOR 说明 - 为什么不调用赋值/复制构造函数
- 防止在复制构造函数中隐式调用基构造函数
- 为用户定义的类正确调用复制构造函数/赋值运算符
- 具有已删除移动和复制构造函数的类的就地构造
- 复制构造函数隐式转换问题
- 复制构造函数中的递归调用