C++ 类和动态内存分配

2014/11/22 01:15 AM posted in  C++

动态内存和类

动态内存如此灵活,在类中也十分常用。

如果在构造函数的时候使用new,那么无论是构造,赋值,复制,析构都需要注意

如果在类中有个static静态成员变量,便可以在类外用作用域解析运算符直接赋值,但是要指出变量类型,如:

int A::num = 0;

如果静态成员是const或者枚举,则可以在类声明初始化。

在复制,赋值过程中,可能会用到临时变量,如果在类中存在动态内存,那么给一个对象赋值时,是一个临时变量给这个对象赋值,过程:

  1. 创建临时变量,其中包括以后指向动态内存空间的指针
  2. 将临时变量成员依次赋值给要赋值的对象
  3. 释放临时变量,包括释放那段动态内存

很明显,这样形成了一个野指针。而这个复制过程被成为浅赋值。也就是由编译器默认复制构造函数实现的。但是,对于使用动态内存的类来说,这样明显是有问题了。因此,要使用深度复制。

深度复制就是使用复制构造函数和重载赋值运算符。

静态类成员函数

可以将成员函数声明为静态的(函数声明包含关键字static)

  1. 不能通过对象调用静态成员函数
  2. 静态成员函数甚至不能使用this指针
  3. 如果静态成员函数是在共有部分声明的,则可以使用类名和作用域解析运算符来调用它
  4. 由于静态成员函数不与特定的对象相关联,因此只能使用静态数据成员
  5. 可以使用静态成员函数设置类级标记,以控制某些类接口的行为

在构造函数中使用new时应注意的事项

  1. 如果在构造函数中用了new,则应在析构函数中使用delete
  2. 如果使用new[],那应该使用delete[]
  3. 如果有多个构造函数,应该使用相同的new格式,因为只有一个析构函数,要保证兼容性
  4. 应该定义一个赋值构造函数,通过深度复制讲一个对象初始化为另一个对象(初始化,形参调用)
  5. 应该定义一个赋值运算符,通过深度复制将一个对象赋值给另一个对象

指针和对象之间的使用,和指针和结构体等的使用方式相同。善待指针!

为了防止隐式转换可以使用explicit关键字。

初始化列表

应该是一个星期前,韩祥波老师把我叫讲台上做一个关于初始化列表的题,不过到现在我才知道什么是初始化列表= =。

其实就是C++为const常量初始化的一种方式,只能用在构造函数上。

如果Queue类中有个叫qsize的常量,常量除了初始化是不允许被赋值的,那么就使用初始化列表进行初始化:

Queue (int qs):qsize(qs)
{
...
}

其他变量也可以用初始化列表进行初始化。其初始化的顺序和类声明中的顺序相同,和初始化列表的顺序无关。

C++11给diao,他可以在类声明中,直接初始化,甚至就是直接默认参数。


就像之前说的,就是在总结的时候浪费时间,那么我节约总结的时间来保证进度,那么代价就是总结不详细。但是有弊也有利,我现在很明确每一篇总结的重点,难点。因为写的都是重点难点。