C++ sizeof操作符

new和delete不表达式

new和delete表达式动态创建和释放数组,这两种表达式也可用于动态创建和释放单个对象。
定义变量时必须指定其数据类型和名字。而创建动态数组时,只需指定其数据类型,而不必为该类型命名。

动态创建对象的默认初始化
如果不提供显示的初始化。动态创建对象在函数内的变量初始化方式相同。
对于类类型的对象,用该类的默认构造函数初始化;而内置类型的对象则无初始化。

如果内存空间耗尽 bad_alloc,系统将抛出bad_alloc  异常。
撤销动态创建的对象
delete表达式释放指针所指向的地址空间。
如果指针指向不适用new分配的内存地址,则在该指针上使用delete是不合法的。

c++没有明确定义如何释放指向不是用new分配的内存地址的指针。下面提供了一些安全的不安全的delete表达式。
    int i;
    int *pi = &i;
    string* str = "dwarves";
    double *pd = new double(33);
    delete str;//error
    delete pi;//error
    delete pd;
值得注意的是编译器可能会拒绝编译str的delete语句。编译器知道str并不是一个指针,因此会在编译时就能检查出这个错误。
第二个错误比较隐蔽:编译器不能断定一个指针指向什么类型,尽管这个语句是错误的,但在大部分编译器上仍能通过。
零值指针删除
c++保证:删除零指针是安全的。

删除指针后,该指针编程悬垂指针。悬垂指针指向曾经存放对象的内存,但该对象已经不存在了。
悬垂指针往往导致程序错误,而且很难检测出来。

一旦删除了指针所指向的对象,立即将指针置为0,这样就非常清楚的表明指针不再指向任何对象。

const对象动态分配和回收
const int*pci = new const int(1024);
与其他常量一样,动态创建const对象必须在创建时初始化,并且一经初始化,其值就不能再修改。
上述new表达式返回指向int型const对象指针。
与其他const对象的地址一样,由于new返回的地址存放的的是const对象,因此该对象只能赋给const指针。
对于类类型的const动态对象,如果该类提供额默认的构造函数,则此对象可隐式初始化:const string *pcs  = new const string;
new 表达式没有显示初始化pcs所指向的对象,而是隐式的将pcs所指向的对象初始化为空的string。
内置类型对象或未提供默认构造函数的类类型对象必须显示初始化。

警告:动态内存管理容易出错

1.删除指向动态分配内存的指针失败,因而无法将该块内存返还给自由存储区。删除动态分配内存失败的称为“内存泄漏”。
内存泄漏很难发现,一般需要等应用程序运行了一段时间后,耗尽了所有内存空间时,内存泄漏才会显现出来
2.读写已删除对象,如果删除指针所指向的对象之后,将指针置为0置,则比较容易检测出这类错误。
3.对同一内存空间使用两次delete表达式。当两个指针指向同一个动态创建的对象,删除时就会发生错误。
如果在其中一个指针上做delete运算,将该对象的内存空间返还给自由存储区,然后接着delete第二个指针,此时则自由存储区可能会被破坏。

操纵动态分配内存时,很容易发生上述错误,但这些错误却难以跟踪和修正。

删除const对象
尽管程序员不能改变const对象的值,但可以撤销对象本身。如同其他动态对象一样,const对象也是使用删除指针来释放:
delete pic

类型转换

类型转换c++中某些类型之间存在相关的依赖关系。若两种类型相关,则可能需要某种类型的操作数位置上,使用该类型的相关性对象或值。
如果两个类型之间存在相互转换,称这两个类型学相关。
隐式类型转换规则
c++定义了算术类型之间的内置转换以尽可能防止精度损失。
如果表达式的操作数分别为整型和浮点型,则整型的浮点数被转换为浮点数。
在赋值操作中,因为不可能更改左操作数的对象的类型,因此左操作数的类型占主导地位。
如果赋值操作的左右操作数类型不同,则右操作数会被转换为左操作数。

何时发生隐式类型转换
编译器在必要时将类型转换规则应用到内置类型和类类型的对象上。下列情况下发生隐式类型转换:
再混合类型的表达式中,其操作数被转换为相同类型;
用作条件的表达式被转换为bool类型;
用以表达式初始化某个变量,或将一表达式赋值给某个变量,则该表达式转化为该变量类型。

算数转换

算术转换规则定义了一个类型转换层次,该层次规定了操作数应该按什么次序转换为表达式中最宽的类型。
包含多种类型的表达式中,转换规则要确保计算值的精度。
例如一个操作数的类型是long double ,则无论另一个操作数是什么类型,都将被转换为long double。
最简单的转换为整型提升:
对于所有比int小的整型,包括char、signed char 、unsigned char 、short 、和 unsigned short,如果该类型的所有可能的值都能包容在int 内,
他们就会被提升为int型,否则,他们将会被提升为 unsigned int。如果将bool值提升为int,则false转换为0,而true则转换为1。

1.有符号与无符号类型之间的转换

包含short和int类型的表达式,short类型的值转换为int。
long和unsigned int的转换也一样。如果long足够表示unsigned int的所有值,就将insigned int 转换为long 。否则,全部转换为 unsigned long。
在32位 机器上,long和int型通常用一个字长表示,因此当表达式包含unsigned int  和long两种类型,其操作数都应该转换为unsigned long型。
对于包含signed 和unsigned int 型表达式。表达式中signed 回被转化为unsigned。

2.理解算术转换

算术转换过程中,要么是将操作数从转换为表达式中的最大类型,要么是在赋值表达式中将右操作数转换为左操作数。

其他隐式转换
在使用数组时,大多数情况下数组都会自动转换为指向第一个元素的指针。
不将数组转化为指针的例外情况用:
数组用作取地址(&)操作符或sizeof操作符的操作数,或引用数组对数组的应用进行初始化时。不会将数组转化为指针。
c++提供另外两种指针转换:指向任意数据类型的指针都可以转化为void *类型;整型数值常量0可转换为任意指针类型
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值