明天早上我正准备自己参加考试。我正在努力进行下面的C ++演练。 我已经运行了代码并使用cout来检查程序的执行情况。我注意到的第一件事就是程序在类“one”中调用默认构造函数3次,仅用于main中的第一个对象。我对代码的执行感到困惑。
#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,
时,为什么它连续三次被调用,那么它会调用t2(4, 2, 8, 3);
?
如果代码太长,我很抱歉,但我真的需要帮助来理解它。
请指教。谢谢。
答案 0 :(得分: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";
}
答案 1 :(得分:2)
你会看到类“一”和类“二”的构造函数都发生了三次,因为这两个对象的三个实例都被创建了。
如果仔细查看插入器友元函数,则第一类和第二类都是通过值而不是通过引用传递的。必须通过默认的复制构造函数(您尚未实现)创建临时实例。如果您想取消额外的实例化,请将插入器功能更改为:
friend ostream &operator<<(ostream &, one &obj);
friend ostream &operator<<(ostream &, two &obj);
当我进一步观察时,两个有2个成员变量类型1,所以你会看到更多的构造函数。
最后,像这样的测试类应命名为foo和bar。一,二甚至很难与自己沟通。 (IMHO)
答案 2 :(得分:1)
从main中的第一个对象。调用“one”的两个默认构造函数,因为类“two”有两个类“one”的对象,一个默认构造函数被称为“Two”正常。
答案 3 :(得分: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,它调用一个构造函数并打印“make one one” 对于t4,它执行默认构造函数并打印“one one made”
cout << t3 << t4;