默认构造函数调用

问题描述:

我正在学习使用练习考试的C++考试。我在确定何时调用某些构造函数时遇到问题。代码是 -默认构造函数调用

using namespace std; 
#include <iostream> 

class Fraction 
{ 
    private: 
    int numerator, denominator; 
    public: 
    Fraction(int = 0, int = 1); 
    friend ostream& operator<<(ostream&, const Fraction&); 
    }; 

void debug(Fraction, Fraction); 
Fraction task(Fraction&, const Fraction&); 

int main() 
    { 
    Fraction * A[6], * B; // Line 1 
    Fraction C(3), D(C); // Line 2 
    Fraction E[4], F = D; // Line 3 
    Fraction G, H(3, 4); // Line 4 
    debug(C, D); // Line 5 
    B = new Fraction; // Line 6 
    F = task(H, C); 
    delete B; 
    return 0; 
    } 

void debug(Fraction X, Fraction Y) 
{ 
    cout << X << endl << Y << endl; 
} 

Fraction task(Fraction& X, const Fraction& Y) 
{ 
    Fraction Z; 
    Z = Fraction(5, 2); // Line 7 
    return 1; // Line 8 
} 

现在,我认为在3种类型的实例中调用默认的复制构造函数。

实施例1 -

 Fraction A(1,2); 

     Fraction B(A); 

实施例2 -

 Fraction A(1,2); 

     Fraction A = B; 

3 - 当一个对象被作为参数传递到 - 当一个对象从一个函数

4返回功能

有两个问题,我似乎无法回答 -

问题1 - 考虑上面的源代码。当编译并执行标记为“第3行”和“第4行”的 语句时,将针对这些语句中的每个 对构造函数调用类“分数”多少次?

答案是 - d)线路3:5个通话线路4:2个来电

的这个问题的答案是D.然而,当我回答这个问题,我得到不同的结果 -

Fraction E[4], F = D; // Line 3 

我看到默认的构造函数被调用5次,E [4],但我认为这这种说法也相当于阵列 -

Fraction E[4], Fraction F(D); 

因此,默认构造函数被调用5次,复制构造函数一次。显然,这是不正确的,因为构造函数只被调用5次。我没有看到我的错误在哪里。

我的另一个问题是在以下问题 -

  1. 考虑(上页)图2中的源代码。当编译并执行标记为“第7行”和“第8行”的 语句时,将针对这些语句中的每个 对构造函数调用类“分数”多少次?

    答案是 - d)7号线:1次通话中的线路8:1的呼叫

    Fraction task(Fraction& X, const Fraction& Y) 
        { 
         Fraction Z; 
         Z = Fraction(5, 2); // Line 7 
         return 1; // Line 8 
        } 
    

    我原本以为默认构造函数将被调用,以创建分数(5,2一个临时对象)那么复制构造函数会将Fraction(5,2)复制到Z.这实际上是默认赋值运算符的操作吗?至于第8行,这是调用复制构造函数,因为它正在返回一个Fraction类型的对象?

一些问题,而我在这里 -

会 -

debug(B, C) 

调用拷贝构造函数两次通过分数对象B和C的副本?

是 -

F = task(H, C); 

调用默认的赋值运算符,以及为F已作为初始化Fraction对象?

+0

为什么不在调试器中运行此代码? – 2013-03-24 02:03:36

+0

对不起,如果这不能回答你的问题。该程序正在使用默认的构造函数。我试图在默认的构造函数被调用时做笔记。如果有一个调试器会告诉我,那会很好。不过,我想明白为什么我会占用更多的电话而不是分配问题的答案。就像第3行一样,我只是为了一个电话而不是答案。关于我的逻辑的东西是错误的。 – jonnywalkerr 2013-03-24 02:08:28

+0

你的代码是否被编译?至少不在g ++ 4.7.2 – gongzhitaao 2013-03-24 02:10:27

你基本上想知道什么时候调用默认的构造函数和拷贝构造函数。

关于第一个问题:

Fraction E[4], F = D; // Line 3 

E[4]Fraction对象的数组,它调用默认的构造函数的4倍,因为你没有显式调用任何其它的构造函数初始化的对象。由于在第2行对象D已经构建,因此,F是使用复制构造函数构造的,在这种情况下,编译器会为您生成一个,因为您没有为自己定义一个。 所以在这种情况下,4个默认构造函数调用和一个拷贝构造函数调用。 在第4行,两个对象都调用默认的构造函数,所以在默认的ctor上调用两次。

debug(B, C) 
call the copy constructor twice to pass copies of Fraction objects B and C? 

是的,因为参数是按值在debug功能过去了,所以拷贝构造函数被调用这两个BC

在一般情况下,拷贝构造函数调用在以下情况:

  1. 当使用现有对象实例化一个对象时(如F= DF(D)
  2. 当传递一个物体的价值。
  3. 通过值从函数返回对象时。

希望这给你足够的信息来理解代码。

+0

谢谢。似乎我忘记了声明数组的容量是显式的,而不是元素的数量+ 1。如果我可能会问,说我声明Fraction F(1,2),然后复制一个现有的对象,比如F =分数(3,4)。这会调用默认的构造函数和默认赋值运算符吗? – jonnywalkerr 2013-03-24 02:15:12

+0

@Jonnywalkerr Fraction(1,2)将调用默认构造函数,F(3,4)也会调用默认构造函数。由于F已经创建,所以F = Fraction(3,4)将调用复制赋值操作符,编译器在这种情况下为您生成。 – taocp 2013-03-24 02:30:14

+0

因此,编译器同时生成一个拷贝构造函数和一个拷贝赋值操作符。调用复制构造函数来处理将数据成员从一个成员逐个成员复制到新声明的对象。这与默认赋值运算符的区别在于赋值运算符将项目中的项目复制到已经初始化的对象。它是否正确?另外,对于像F = Fraction(3,4)这样的东西,它只是复制赋值操作符被调用吗?或者是默认的构造函数,以及生成一个临时对象Fraction(3,4)? – jonnywalkerr 2013-03-24 03:38:46