0

我正在为明天早上的考试做准备。我正在为下面的 C++ 演练而苦苦挣扎。我已经运行了代码并使用 cout 来检查程序的执行情况。我注意到的第一件事是程序只为 main 中的第一个对象调用了类“one”中的默认构造函数 3 次。我真的对代码的执行感到困惑。

    #include <iostream>
    using namespace std;

    class one {
    int n;
    int m;
      public:
    one() { n = 5; m = 6; cout << "one one made\n"; }
    one(int a, int b) {
      n = a;
      m = b;
      cout << "made one one\n";
    }
    friend ostream &operator<<(ostream &, one);
    };

    ostream &operator<<(ostream &os, one a) {
    return os << a.n << '/' << a.m << '=' <<
     (a.n/a.m) << '\n';
    }

    class two {
    one x;
    one y;
      public:
    two() { cout << "one two made\n"; }
    two(int a, int b, int c, int d) {
      x = one(a, b);
      y = one(c, d);
      cout << "made one two\n";
    }
    friend ostream &operator<<(ostream &, two);
    };

    ostream &operator<<(ostream &os, two a) {
    return os << a.x << a.y;
    }

    int main() {
    two t1, t2(4, 2, 8, 3);
    cout << t1 << t2;
    one t3(5, 10), t4;
    cout << t3 << t4;
    return 0;
    } 

我不明白第一件事。当 main 调用第一个默认构造函数时two t1,,为什么它会连续调用 3 次然后它会调用t2(4, 2, 8, 3);

如果代码太长,我很抱歉,但我真的需要帮助才能理解它。

请指教。谢谢你。

4

4 回答 4

4

当我运行代码时,我得到了这个结果:

one one made
one one made
one two made
one one made
one one made
made one one
made one one
made one two

这是因为:

two t1;
one one made //t1.x; parameterless 'one' constructor called by default
one one made //t1.y; parameterless 'one' constructor called by default
one two made //t1; parameterless 'two' constructor

t2(4, 2, 8, 3)
one one made //t2.x; default constructor as variable not present in initialization list

one one made //t2.y; default constructor as variable not present in initialization list

made one one //x = one(a, b) executed now
made one one //y = one(c, d) executed now
made one two //t2(int..) constructer called

请注意,在 t2 的情况下,x 和 y 被构造了两次,因为没有初始化列表。为避免这种情况,您可以使用:

two(int a, int b, int c, int d): x(a,b), y(c,d)
{
cout << "made one two\n";
}
于 2012-04-10T05:21:25.720 回答
2

您将看到类“one”和类“two”的构造函数都出现了 3 次,因为这两个对象的三个实例都被创建了。

如果你仔细看一下插入器友元函数,第一类和第二类都是按值传递的,而不是按引用传递的。必须通过默认复制构造函数(您尚未实现)创建临时实例。如果您想取消额外的实例化,请将您的插入器函数更改为:

friend ostream &operator<<(ostream &, one &obj); 
friend ostream &operator<<(ostream &, two &obj); 

当我进一步看时,两个有 2 个类型为 1 的成员变量,所以你会看到我认为的更多构造函数。

最后,像这样的测试类应该命名为 foo 和 bar。一和二连自己都难以沟通。(恕我直言)

于 2012-04-10T05:08:13.123 回答
1

从 main 中的第一个对象开始。调用“one”的两个默认构造函数,因为“two”类有两个“one”类的对象,并且正常调用“Two”的一个默认构造函数。

于 2012-04-10T05:27:20.070 回答
1

这是我看到的输出:

one one made
one one made
one two made
one one made
one one made
made one one
made one one
made one two
5/6=0
5/6=0
4/2=2
8/3=2
made one one
one one made
5/10=0
5/6=0

这对我来说很有意义。我没有看到第一个对象的默认构造函数被调用 3 次。

就输出而言,这里会发生什么:

two t1, t2(4, 2, 8, 3);

对于 t1,它为类中定义的两个对象调用一个的默认构造函数

two (one x and one y)

所以输出是“一做”和“一做”接下来它执行两个的默认构造函数所以输出是“一二做”下一个对于t2,它再次为x和y调用默认构造函数一所以输出是“一个制造”和“一个制造”接下来它执行

x = one(a,b) and y =one(c,d)

所以现在它在 two() 的构造函数中打印“做了一个”和“做了一个”,因为我们已经“做了一个两个”,同样被打印了......

cout << t1 << t2;

one t3(5, 10), t4;

再次对于此语句,对于 t3,它调用 one 的构造函数并打印“make one one” 对于 t4,它执行默认构造函数并打印“one one made”

cout << t3 << t4;
于 2012-04-10T05:31:39.600 回答