#include <iostream.h>
class A {
public:
A(int n):num(n) { Out( ); }
A(const A& rhs):num(rhs.num)
{Out( );}
void Out( ) {cout<<num<<endl; }
private:
int num;
};
class B:public A {
public:
B(A& a) :obj(a),A(1) { }
void Out( ) { obj.Out( ); }
private:
A obj;
};
int main( ) {
A a(8);
B b1(a);
B b2(b1);
b2.Out();
return 0;
}
输出为8 1 8 1 8 8
实在不理解最后3个数字
14 个解决方案
#1
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
#2
A a(8); 构造函数输出8
B b1(a); 掉用B构造,先执行A(1)创建临时对象,输出1,后运行 obj(a)输出8
B b2(b1); 没有显示的拷贝构造,调用b(a)进行转换,输出 1,8
b2.Out(); 输出8
return 0;
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
拷贝构造如果没有声明,类会自动生成。但是 该类中有B( a a)这种,通过类型转换来实现的靠背构造,编译器会优先选择,个人定义的。
#7
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
int main() {
A a(8); //调用:A(int n) a.num=8
B b1(a); //B(A& a),先调用A(1)后 构造b1.obj (基类不先构造如何构造子类) b1.num=1, b1.obj.num= 8
B b2(b1); //调用默认拷贝构造(浅拷贝),此时b2和b1值相同的,所有b2.num=1 ,b2.obj.num=8
b2.Out();
return 0;
}
#1
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
#2
A a(8); 构造函数输出8
B b1(a); 掉用B构造,先执行A(1)创建临时对象,输出1,后运行 obj(a)输出8
B b2(b1); 没有显示的拷贝构造,调用b(a)进行转换,输出 1,8
b2.Out(); 输出8
return 0;
#3
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8
拷贝构造如果没有声明,类会自动生成。但是 该类中有B( a a)这种,通过类型转换来实现的靠背构造,编译器会优先选择,个人定义的。
#7
A a(8) ------> 8
B b1(a) // B 中包含两个 A 对象, 一个是基类, 一个是成员, 先构造基类输出 1, 再构造成员输出 8 ------------> 1 8
B b2(b1) // b1 中基类 A 对象值为 1, 成员 A 对象值为 8
// 先执行基类的拷贝输出 1, 在执行成员的拷贝输出 8 -------------------> 1 8
b2.Out() // B 中定义的 Out 函数覆盖了基类 A 中的 Out 函数, 所以执行的是 B 的 Out, 输出成员 A 的值 8 -------------------> 8