转载自http://blog.sina.com.cn/shuiwuhendeboke    颗颗的博客

(1)作用域不同

不用new:作用域限制在定义类对象的方法中,当方法结束时,类对象也被系统释放了。(安全不会造成内存泄露)

用new:创建的是指向类对象的指针,作用域编程了全局,当程序结束时,必须用delete[] 来删除,系统不会自动释放。(不注意可能造成内存泄露)

(2)一个类对象,一个指向类对象的指针

起初刚学C++时,很不习惯用new,后来看老外的程序,发现几乎都是使用new,想一想区别也不是太大,但是在大一点的项目设计中,有时候不使用new的确会带来很多问题。当然这都是跟new的用法有关的。new创建类对象,使用完后需使用delete删除,跟申请内存类似。所以,new有时候又不太适合,比如在频繁调用场合,使用局部new类对象就不是个好选择,使用全局类对象或一个经过初始化的全局类指针似乎更加高效。

一、new创建类对象与不new区别

下面是自己总结的一些关于new创建类对象特点:

new创建类对象需要指针接收,一处初始化,多处使用

new创建类对象使用完需delete销毁

new创建对象直接使用堆空间,而局部不用new定义类对象则使用栈空间

new对象指针用途广泛,比如作为函数返回值、函数参数等

频繁调用场合并不适合new,就像new申请和释放内存一样

二、new创建类对象实例

1、new创建类对象例子:

CTest* pTest = new CTest();

delete pTest;

pTest用来接收类对象指针。

不用new,直接使用类定义申明:

CTest mTest;

此种创建方式,使用完后不需要手动释放,该类析构函数会自动执行。而new申请的对象,则只有调用到delete时再会执行析构函数,如果程序退出而没有执行delete则会造成内存泄漏。

2、只定义类指针

这跟不用new申明对象有很大区别,类指针可以先行定义,但类指针只是个通用指针,在new之前并为该类对象分配任何内存空间。比如:

CTest* pTest = NULL;

但使用普通方式创建的类对象,在创建之初就已经分配了内存空间。而类指针,如果未经过对象初始化,则不需要delete释放。

一个类的实例化对象所占空间的大小?

注意不要说类的大小,是类的对象的大小.

首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的。
用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小。
如果
Class A;
A obj;
那么sizeof(A)==sizeof(obj)
那么sizeof(A)的大小和成员的大小总和是什么关系呢,很简单,一个对象的大小大于等于所有非静态成员大小的总和。
为什么是大于等于而不是正好相等呢?超出的部分主要有以下两方面:
1) C++对象模型本身
对于具有虚函数的类型来说,需要有一个方法为它的实体提供类型信息(RTTI)和虚函数入口,常见的方法是建立一个虚函数入口表,这个表可为相同类型的对象共享,因此对象中需要有一个指向虚函数表的指针,此外,为了支持RTTI,许多编译器都把该类型信息放在虚函数表中。但是,是否必须采用这种实现方法,C++标准没有规定,但是这几户是主流编译器均采用的一种方案。
2) 编译器优化
因为对于大多数CPU来说,CPU字长的整数倍操作起来更快,因此对于这些成员加起来如果不够这个整数倍,有可能编译器会插入多余的内容凑足这个整数倍,此外,有时候相邻的成员之间也有可能因为这个目的被插入空白,这个叫做“补齐”(padding)。所以,C++标准紧紧规定成员的排列按照类定义的顺序,但是不要求在存储器中是紧密排列的。
基于上述两点,可以说用sizeof对类名操作,得到的结果是该类的对象在存储器中所占据的字节大小,由于静态成员变量不在对象中存储,因此这个结果等于各非静态数据成员(不包括成员函数)的总和加上编译器额外增加的字节。后者依赖于不同的编译器实现,C++标准对此不做任何保证。

C++标准规定类的大小不为0,空类的大小为1,当类不包含虚函数和非静态数据成员时,其对象大小也为1。

如果在类中声明了虚函数(不管是1个还是多个),那么在实例化对象时,编译器会自动在对象里安插一个指针指向虚函数表VTable,在32位机器上,一个对象会增加4个字节来存储此指针,它是实现面向对象中多态的关键。而虚函数本身和其他成员函数一样,是不占用对象的空间的。

我们来看下面一个例子:(此例子在Visual C++编译器中编译运行)

#include
using namespace std;
class   A  
{  
};  
class   B  
{  
char   ch;  
void   func()  
{  
}  
};  
class   C  
{  
char   ch1;    //占用1字节
char   ch2;   //占用1字节
virtual   void   func()  
{  
}  
};  
class   D  
{  
int   in;  
virtual   void   func()  
{  
}  
};  
void   main()  
{  
A   a;
B   b;
C   c;
D   d;
cout<<sizeof(a)<<endl;//result=1  
cout<<sizeof(b)<<endl;//result=1   //对象c扩充为2个字,但是对象b为什么没扩充为1个字呢?大家帮忙解决
cout<<sizeof(c)<<endl;//result=8  
//对象c实际上只有6字节有用数据,但是按照上面第二点编译器优化,编译器将此扩展为两个字,即8字节
cout<<sizeof(d)<<endl;//result=8  
}

综上所述:

一个类中,虚函数、成员函数(包括静态与非静态)和静态数据成员都是不占用类对象的存储空间的。

对象大小=   vptr(可能不止一个)   +   所有非静态数据成员大小   +   Aligin字节大小(依赖于不同的编译器)

最新文章

  1. pthread_creat()解析及需注意的地方
  2. 移位操作&lt;&lt;和&gt;&gt;,是逻辑数字上的移动(和大端小端无关)
  3. JS模式:策略模式,感觉就是一个闭包存储信息,然后是加一些验证方法--还看了老半天
  4. bzoj1758 [Wc2010]重建计划 &amp; bzoj2599 [IOI2011]Race
  5. linux 开启wifi热点
  6. spring debug
  7. 深入理解java虚拟机之——JVM垃圾回收策略总结
  8. linux_通配符
  9. BoltDB简单使用教程
  10. 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)
  11. python-基于tcp协议的套接字(加强版)及粘包问题
  12. 了解PID控制
  13. 在ServiceModel客户端配置部分中,找不到引用协定“”的默认终结点元素
  14. Oracle&#160;使用SQL*Plus连接数据库
  15. 解决npm ERR! Unexpected end of JSON input while parsing near的方法汇总
  16. activiti 报 next dbid
  17. mysql(mariadb)新建用户及用户授权管理
  18. HDU1816(二分+2-SAT)
  19. AOP 应用 性能
  20. java实现图像的直方图均衡以及灰度线性变化,灰度拉伸

热门文章

  1. MSSQL如何在没有主键的表中删除重复数据
  2. dsfgsdfg
  3. Java 在指定目录建立指定文件名的文件 并输入内容
  4. C++类和对象
  5. linux下JDK1.7安装
  6. 动手动脑:Finally
  7. 转:WebService通用接口
  8. 配置不当导致无法加载odoo-10.0模块
  9. linux bond配置步骤,七种bond模式说明
  10. AFN的初步封装(post、GET、有无参数)