1
#include <iostream>
#include <cstring>
using namespace std;

class foo {
     int number;
     char string[20];
public:
     foo( ) { 
          set(3, 5); 
     }
     void set (int a, int b) { 
          number = a + b;
        strcpy( string, "summer" ); 
     }

     foo (const foo & c ) { 
     }

     void output() { 
          cout << number << ',' << string << endl;  
     }
};

void showyanothing (foo);

int main() {
     foo a, b;
     showyanothing( a );
     a.output();
     b.output();
}

void showyanothing (foo z) { 
     cout << "... how are you?\n";
     z.output(); 
}

输出

... hello ...
... how are you?
-1218897013,l·ôl·Y·ôl·À
8,summer
8,summer

带有-1218897013,l·ôl·Y·ôl·À, 的行是复制构造函数创建的对象 Z 中的值。如果我将复制构造函数更改为以下内容,则输出对象 z 将 yield 10, summer.1.2.3。为什么?这些值是从哪里神奇地插入到 Z 中的?

新的复制构造函数

 foo (const foo & c ) { 
     number = c.number + 2;
     strcpy( string, c.string );
     strcat( string, ".1.2.3" );
 }

新输出:

... how are you?
10,summer.1.2.3
8,summer
8,summer

在复制构造函数中,我很困惑的是为什么c.number等于8,而c.string等于夏天?它是从哪里得到这些值的?

4

3 回答 3

4

简单检查一下函数调用

void showyanothing (foo z) 

复制构造函数在这里被调用。由于您在早期代码中有一个复制构造函数并且没有初始化数据成员,因此它会打印随机 val。另一方面,当您编辑复制构造函数时,您会得到结果(即调用以下内容!)

foo (const foo & c ) { 
     number = c.number + 2;
     strcpy( string, c.string );
     strcat( string, ".1.2.3" );
 }

希望它能解决你的疑问:)

于 2013-03-11T03:48:58.740 回答
0

复制构造函数的第一个版本不会初始化 foo 的成员变量。因此number,andstring将包含随机数据——无论在 RAM 中新对象被实例化的位置发生了什么。

第二个版本根据通过引用传入的对象(我们应该“复制”的对象)正确地将值分配给成员变量。在这种情况下,您正在传入a(因为您调用showyanothing(a)),它是使用默认构造函数实例化的,它给了它数字 8 和字符串“summer”。

于 2013-03-11T03:50:06.827 回答
0

无论您是否初始化,对象都会占用内存。内存包含一些任意值。如果你不初始化它,它可以是任何东西。这解释了你得到的初始垃圾输出。

接下来,您提供合理的复制构造函数,它根据传递给它的源对象初始化对象。在开始时,您main()创建a使用默认构造函数构造的对象,因此由于调用而将其number成员设置为 8 。函数通过值传递其参数,这意味着使用接收 object 的复制构造函数创建类的新实例,它将's (即 8)添加 2并复制.set(3,5)showyanothing (foo z)fooaanumberstring

于 2013-03-11T03:52:45.367 回答