#include <iostream>
using namespace std;
/*
创建对象A
创建对象BA
创建对象A
创建对象BA
销毁对象BA
销毁对象A
销毁对象BA
销毁对象A
创建对象C
创建对象BC
创建对象C
创建对象BC
line=173 fun_bc1
line=178 fun_bc2
销毁对象BC
销毁对象C
line=173 fun_bc1
line=178 fun_bc2
销毁对象C
---------------------------------------------
size0f(A)=4
size0f(B)=4
size0f(C)=12
size0f(BA)=8
size0f(BC)=16
size0f(D)=8
size0f(BD)=12
创建对象D
line=123
创建对象D
line=198
line=198
size0f(Edata)=4
测试结论:
1.子类对象大小=当前子类成员函数大小+父类对象大小+有虚函数的话还要加4(这个是实现动态虚表的指针)
2.成员函数不占用对象空间大小,成员函数是在代码段
3.若设置的类可以被其他类可继承,在析构函数前应该加virtual
基类的析构函数加了virtual就可以动态绑定派生类的析构函数,这样的话,在执行多态后删除其对象,就可以在删除对象的时候执行派生类的析构函数了(当然执行基类的析构函数是一定会的)。否则不会执行派生类的析构函数。
*/
class A //1字节 2个成员函数不占空间,本应该是0字节,但创建对象要用空间,所以编译器为其分配1个字节大小
{
public:
A()
{
cout<<"创建对象A"<<endl;
};
virtual ~A()
{
cout<<"销毁对象A"<<endl;
};
//void fun_a1();
//void fun_a2();
};
/*
void A::fun_a1()
{
cout<<"fun_a1"<<endl;
}
void A::fun_a2()
{
cout<<"fun_a2"<<endl;
}
*/
class B //4字节 有一个int成员变量,所以占用4字节
{
public:
B()
{
cout<<"创建对象B"<<endl;
};
~B()
{
cout<<"销毁对象B"<<endl;
};
int idata;
void fun_b1();
void fun_b2();
};
void B::fun_b1()
{
cout<<"fun_b1"<<endl;
}
void B::fun_b2()
{
cout<<"fun_b2"<<endl;
}
class C //12字节 有2个int成员变量+1个虚表,所以占用12字节
{
public:
C()
{
cout<<"创建对象C"<<endl;
};
~C()
{
cout<<"销毁对象C"<<endl;
};
int idataC;
int idataD;
virtual void fun_c1();//虚表4字节 这个不加virtual,程序会在delete base_c;崩溃,因为BC类的fun_c1加virtual
void fun_c2();//0-字节
};
void C::fun_c1()
{
cout<<"line="<<__LINE__<<" fun_c1"<<endl;
}
void C::fun_c2()
{
cout<<"line="<<__LINE__<<" fun_c2"<<endl;
}
class D //8字节 有1个int成员变量,占用4字节 还有虚函数占用4字节(一个或多个都只占用一个指针)
{
public:
D()
{
cout<<"创建对象D"<<endl;
};
~D()
{
cout<<"销毁对象D"<<endl;
};
int idataD;
virtual void v_fun1();
virtual void v_fun2();
virtual void v_fun3();
};
void D::v_fun1()
{
cout<<"line="<<__LINE__<<endl;
}
void D::v_fun2()
{
cout<<"line="<<__LINE__<<endl;
}
void D::v_fun3()
{
cout<<"line="<<__LINE__<<endl;
}
class BA:public A //4+1(0)-->4 BA成员变量占用4字节,A占用1字节,但因为A没有成员变量,编译器会进行优化成0字节,所以这个也只占用4字节.但VC测试可能没有优化还是8个字节
{
public:
BA()
{
cout<<"创建对象BA"<<endl;
};
~BA()
{
cout<<"销毁对象BA"<<endl;
};
int idata;
};
class BC:public C //4+8-->12 成员变量4字节+C类12字节共16字节
{
public:
BC()
{
cout<<"创建对象BC"<<endl;
};
~BC()
{
cout<<"销毁对象BC"<<endl;
};
int idata;
virtual void fun_c1();//0-字节 因为C类中已有virtual表,所以这里虚表不占空间了
void fun_c2();//0-字节
};
void BC::fun_c1()
{
cout<<"line="<<__LINE__<<" fun_bc1"<<endl;
}
void BC::fun_c2()
{
cout<<"line="<<__LINE__<<" fun_bc2"<<endl;
}
class BD:public D //8+8(4)-->12 内部成员变量4字节+虚函数4字节+D类成员变量4字节=12字节
{
public:
BD(){};
~BD(){};
virtual void v_fun1();//4
virtual void v_fun2();
virtual void v_fun3();
int idata;//4
};
void BD::v_fun1()
{
cout<<"line="<<__LINE__<<endl;
}
void BD::v_fun2()
{
cout<<"line="<<__LINE__<<endl;
}
void BD::v_fun3()
{
cout<<"line="<<__LINE__<<endl;
}
typedef enum Edata
{
KIDEL=1,
KRUN=2,
};
int main()
{
A *base_a;
BA *ba = new BA;
BA *ba2 = new BA;
if (ba)
{
delete ba;
}
base_a = ba2;
if (base_a)
{
delete base_a;
}
C *base_c;
BC *bc = new BC;
BC *bc2 = new BC;
bc->fun_c1();
bc->fun_c2();
if (bc)
{
delete bc;
}
base_c = bc2;//因为 C类的构造函数不是virtual 虚函数,在基类指向子类对象进行删除时,就不会调用子类的析构,从而会造成派生类中申请的空间就得不到释放从而产生内存泄漏
bc2->fun_c1();
bc2->fun_c2();
if (base_c)
{
delete base_c;
}
cout<<"---------------------------------------------"<<endl;
D *d;
BD *bd;
cout<<"size0f(A)="<<sizeof(A)<<endl;
cout<<"size0f(B)="<<sizeof(B)<<endl;
cout<<"size0f(C)="<<sizeof(C)<<endl;
cout<<"size0f(BA)="<<sizeof(BA)<<endl;
cout<<"size0f(BC)="<<sizeof(BC)<<endl;
cout<<"size0f(D)="<<sizeof(D)<<endl;
cout<<"size0f(BD)="<<sizeof(BD)<<endl;
d = new (D);
d->v_fun1();
bd = new (BD);
bd->v_fun1();
d = bd;
d->v_fun1();
cout<<"size0f(Edata)="<<sizeof(Edata)<<endl;
return 0;
}