类对象大小测试2

#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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章