C++之类的一些特性(反汇编)

一、结构体与类

  C++中,结构体和类都具有构造函数、析构函数和成员函数。

  区别:结构体的访问控制默认为public,而类的默认访问控制是private

  特点:对于C++中的结构体而言,public、private、protected的访问控制都是在编译器进行检查,当越权访问时,编译过程中会检查出此类错误并给予提示。编译成功后,程序在执行的过程中不会在访问控制方面做任何检查和限制

  因此,反汇编中,C++中的结构体与类没有分别,两者的原理相同,只是类型名称不同。

二、对象的内存布局

  类的实例化对象都存放在堆中!!!!(可以通过反汇编实例化代码,可知实例的首地址一般都在堆中)

  对象的大小只包含数据成员,类成员函数属于执行代码,不属于类象的数据。

 

#include<iostream>

class CNumber
{
public:
	CNumber()
	{
		m_nOne = 1;
		m_nTwo = 2;
	}

private:
	int m_nOne;
	int m_nTwo;

};
int main()
{
	CNumber Number;
	printf("The adress of class CNumbe : %d \n",&Number);     // 这里应该为%X,所以结果显示不同
	printf("The size of class CNumbe : %d \n",sizeof(CNumber));
	printf("The size of class CNumbe : %d \n",sizeof(Number));
	return 0;
}

 

  

        

  对象在内存中至存放数据成员。

提示:为什么类中不能定义自身的对象?

#include<iostream>

class CNumber
{
public:
	CNumber()
	{
		m_nOne = 1;
		m_nTwo = 2;
	}
	
	CNumber Num;   // 这里是对自身对象的实例化......
private:
	int m_nOne;
	int m_nTwo;

};
int main()
{
	CNumber Number;
	printf("The adress of class CNumbe : %d \n",&Number);
	printf("The size of class CNumbe : %d \n",sizeof(CNumber));
	printf("The size of class CNumbe : %d \n",sizeof(Number));
	return 0;
}

编译提示:

解释:因为类需要在申请内存的过程中计算出自身的实际大小,以用于实例化。如果在类中定义了自身的对象,在计算各数据成员的长度时,又会回到自身,这样就形成了递归定义,而这个递归并没有出口,是一个无限的循环递归定义,所以不能定义自身对象作为类成员。

但是可以定义自身类型的指针,因为任何类型的指针在内存中都是32位,4个字节,等同一个常量值。

例:

  将上面代码中 CNumber num;修改为 CNumber *num;

结果如下:

  

注意:这里实例化后的Number对象,有三个数据成员,一个指向了有3个变量的结构的指针,两个变量.

1、空类

 

#include<iostream>

class CNumber
{


};
int main()
{
	CNumber Number;
	printf("The adress of class CNumbe : %X \n",&Number);
	printf("The size of class CNumbe : %d \n",sizeof(CNumber));
	printf("The size of class CNumbe : %d \n",sizeof(Number));
	return 0;
}

 

  结果:

debug版反汇编:

 

10:       CNumber Number;                          // 这句直接不会编译
11:       printf("The adress of class CNumbe : %X \n",&Number);
00401048   lea         eax,[ebp-4]                     // 有地址
0040104B   push        eax
0040104C   push        offset string "The adress of class CNumbe : %X "... (00431044)
00401051   call        printf (00408170)
00401056   add         esp,8
12:       printf("The size of class CNumbe : %d \n",sizeof(CNumber));
00401059   push        1                           // 只分配一个字节
0040105B   push        offset string "The size of class CNumbe : %d \n" (0043101c)
00401060   call        printf (00408170)
00401065   add         esp,8
13:       printf("The size of class CNumbe : %d \n",sizeof(Number));
00401068   push        1
0040106A   push        offset string "The size of class CNumbe : %d \n" (0043101c)
0040106F   call        printf (00408170)
00401074   add         esp,8

 

  Release版本基本相同

 

 

posted @ 2012-08-18 11:23  xiaolongxia  阅读(455)  评论(0)    收藏  举报