简体   繁体   English

通过示例了解复制构造函数和赋值运算符

[英]Understanding copy constructors and assignment operators with an example

I've been reading the book "An Introduction to Design Patterns in C++ with Qt 4" recently and I am confused by the following example (codes are from the book, with a small modification by myself): 我最近一直在阅读“Qt 4中的C ++设计模式简介”这本书,我对以下示例感到困惑(代码来自书中,我自己做了一些小修改):

"fraction.h" “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" “的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<<"]\n\n";
}

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 declarations\n";
    Fraction::report();  //output: [assogns: 0, copies: 2, ctors: 2]

    f4 = twothirds;  // It's an assignment using the assignment operator
    cout<<"before multiply\n";
    Fraction::report();  //output: [assogns: 1, copies: 2, ctors: 2]

    f4 = twothirds.multiply(threequarters);
    cout<<"after multiply\n";
    Fraction::report();  //output: [assogns: 2, copies: 3, ctors: 3]
    // [Question B]: How does the frunction "multiply" creates three Fraction objects?

    return 0;
}

As the comments I left in main.cpp , I got 2 questions. 正如我在main.cpp留下的评论,我有两个问题。

[Question A]: Why Fraction f4 = threequarters using copy constructor rather than assignment? [问题A]:为什么Fraction f4 = threequarters使用复制构造函数而不是赋值?

[Question B]: How does the frunction "multiply" creates three Fraction objects? [问题B]:如何“加倍”创建三个Fraction对象?

Especially for Question B, I can't figure out where are those three objects from. 特别是对于问题B,我无法弄清楚这三个对象在哪里。

Please help me understanding the concepts. 请帮我理解这些概念。 Thanks in advance. 提前致谢。

Question A: Why Fraction f4 = threequarters using copy constructor rather than assignment? 问题A:为什么Fraction f4 =使用复制构造函数而不是赋值?

Answer A: That is the definition of the C++ language. 答案A:这是C ++语言的定义。 If you had used 如果你曾经使用过

Fraction f4;
f4 = threequarters; 

then the second line would use the assignment operator. 然后第二行将使用赋值运算符。

Question B: How does the frunction "multiply" creates three Fraction objects? 问题B:如何“加倍”创建三个Fraction对象?

Answer B: 答案B:

When you call multiply , the argument f2 is created by using copy construction. 调用multiply ,参数f2是使用复制构造创建的。

The line 这条线

return Fraction (m_Numer*f2.m_Numer, m_Denom*f2.m_Denom);

construct on object using the regular constructor. 使用常规构造函数构造对象。

The line 这条线

f4 = twothirds.multiply(threequarters);

assigns the object constructed in multiply to f4 . 分配中构建的物体multiplyf4

Question A: Because in line Fraction f4 = threequarters, f4 doesn't exist yet so copy constructor is called to create a copy of "threequarters". 问题A:因为在Fraction f4 = fourquarters中,f4还不存在所以复制构造函数被调用来创建“fourquarters”的副本。 operator= is only called when object already exists (ie. f4 = twothirds) operator =仅在对象已存在时调用(即f4 = twothirds)

Question B: Fraction multiply(Fraction f2), when twothirds.multiply(threequarters) is executed, function call parameters are "pass by value" (ie. a copy is passed into the function). 问题B:分数乘法(分数f2),当执行twothirds.multiply(四分之三)时,函数调用参数是“按值传递”(即,将副本传递给函数)。 So in this instance a copy of "threequarters" is made and passed into "multiply". 因此,在这种情况下,制作了“四分之三”的副本并将其传递给“乘法”。 Then inside that function you explicitly created a Fraction by calling a constructor. 然后在该函数内部通过调用构造函数显式创建了一个Fraction。 Finally you returned this as Fraction which means a copy of it returned. 最后你把它作为Fraction返回,这意味着它的副本返回了。 So entire function call made 1 copy constructor call to pass it in, 1 constructor call to create the Fraction and 1 copy constructor call to return the Fraction, total 3. 所以整个函数调用使得1个复制构造函数调用传递给它,1个构造函数调用创建Fraction和1个复制构造函数调用以返回Fraction,总共3个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM