#include <string.h>
#include "stdio.h"
#include <iostream.h>class A {
public:
A() {
a = 0;
cout<<"类A的默认构造函数。\n";
}
A(int i) {
a = i;
cout<<"类A的构造函数。\n";
}
~A() {
cout<<"类A的析构函数。\n";
}
void Print() const {
cout<<a<<",";
}
int Geta() {
return a;
}
private:
int a;
};class B : public A {
public:
B() {
b = 0;
cout<<"类B的默认构造函数。\n";
}
B(int i,int j,int k);
~B() {
cout<<"类B的析构函数。\n";
}
void Print();
private:
int b;
A aa;
};B::B(int i,int j,int k):A(i),aa(j) {
b = k;
cout<<"类B的构造函数。\n";
}void B::Print() {
A::Print();
cout<<b<<","<<aa.Geta()<<endl;
}void main()
{
B bb[2];
bb[0] = B(1,2,5);
bb[1] = B(3,4,7);
for(int i = 0; i < 2; i++) {
bb[i].Print();
}

运行结果是:类A的默认构造函数。
类A的默认构造函数。
类B的默认构造函数。
类A的默认构造函数。
类A的默认构造函数。
类B的默认构造函数。
类A的构造函数。
类A的构造函数。
类B的构造函数。
类B的析构函数。
类A的析构函数。
类A的析构函数。
类A的构造函数。
类A的构造函数。
类B的构造函数。
类B的析构函数。
类A的析构函数。
类A的析构函数。
1,5,2
3,7,4
类B的析构函数。
类A的析构函数。
类A的析构函数。
类B的析构函数。
类A的析构函数。
类A的析构函数。
Press any key to continue哪位能给我详细的解释下啊,谢谢啦!!!

解决方案 »

  1.   

    大概是这样的
    先B bb[2];没有定义初始化规则,则调用默认的初始化规则。即默认的构造方法
    定义的是子类对象,先调用子类的默认构造方法,子类的默认构造方法第一行其实是覆盖父类的默认构造方法,只不过没写出来,所以调用父类的默认构造方法,构造方法里面先初始化成员变量,然后执行构造器内部代码打印  类A的默认构造函数。  然后返回子类的默认构造器,初始化子类的成员变量,成员变量又有一个默认初始化规则的aa所以又调用一次类A的默认构造器,打印 类A的默认构造函数。 然后执行子类构造器内部代码 , 打印  类B的默认构造函数。
    数组里面是两个子类型数据,所以打印两遍,即
    类A的默认构造函数。
    类A的默认构造函数。
    类B的默认构造函数。
    类A的默认构造函数。
    类A的默认构造函数。
    类B的默认构造函数。
    然后第二步
    bb[0] = B(1,2,5);
    bb[1] = B(3,4,7);
    这个就定义了规则,所以调用指定的构造方法, 顺序和上面一样,只不过被重新赋值原来的内存里面的对象就不用了  多了一个析构操作,析构的顺序和构造时候是相反的  所以不难理解
    类A的构造函数。
    类A的构造函数。
    类B的构造函数。
    类B的析构函数。
    类A的析构函数。
    类A的析构函数。
    类A的构造函数。
    类A的构造函数。
    类B的构造函数。
    类B的析构函数。
    类A的析构函数。
    类A的析构函数。
    第三步
    for(int i = 0; i < 2; i++) {
    bb[i].Print();
    }
    没啥好说的了
    1,5,2
    3,7,4
    调用完了,程序结束 所有对象回收  再析构一遍
    类B的析构函数。
    类A的析构函数。
    类A的析构函数。
    类B的析构函数。
    类A的析构函数。
    类A的析构函数。