动态内存和类
C++在分配内存时,让程序在运行时决定内存分配,而不是在编译时决定。这样,可更具程序的需要,而不是根据一系列严格的储存类型规则来使用内存。
注意:静态数据成员在类声明中声明,在包含类方法的文件中初始化。初始化时使用作用域运算符来指出静态成员所属的类。但如果静态成员是整型或枚举型const,则可以在类声明中初始化。
警告:在构造函数中使用new来分配内存时,必须在相应的析构函数中时候用delete来释放内存。如果使用new[](包括中括号)来分配内存,则应使用delete[](包括中括号)来释放内存。
特殊成员函数
C++自动提供了下面这些成员函数:
默认构造函数,如果没有定义构造函数;
默认析构函数,如果没有定义;
复制构造函数,如果没有定义;
赋值运算符,如果没有定义;
地址运算符,如果没有定义;
提示:如果类中包含这样的静态数据成员,即其值将在新对象被创建时发生变化,则应该提供一个显式复制构造函数来处理计数问题。
警告:如果类中包含了使用new初始化的指针成员,应当定义一个复制构造函数,以复制指向的数据,而不是指针,这被称为深度复制。复制的另一种形式(成员复制或浅复制)只是复制指针值。浅复制仅浅浅地复制指针信息,而不会深入“挖掘”以复制指针引用的结构。
在构造函数中使用new时应注意的事项
如果在构造函数中使用new来初始化指针成员,则应在析构函数中使用delete。
new和delete必须相互兼容。new对应于delete,new[]对应于delete[]。
如果有多个构造函数,则必须以相同的方式时候用new,要么都带中括号,要么都不带。因为只有一个析构函数,所有的构造函数都必须与它兼容。然而,可以在一个构造函数中使用new初始化指针,而在另一个构造函数中将指针初始化为空,这是因为delete(无论是带中括号还是不带中括号)可以用于空指针。
NULL,0,nullptr:
以前空指针可以用0或NULL来表示。C程序员通常使用NULL。然而C++更喜欢用简单的0.但C++11提供了关键字nullptr。这是一种更好的选择。
有关返回对象的说明。
当成员函数或独立的函数返回对象时,有几种返回方式可供选择。可以返回指向对象的引用、指向对象的const引用或const对象。
使用指向对象的指针
队列模拟
队列有点像栈,但栈在同一段进项添加和删除。这使得栈是一种后进先出的结构,而队列是先进先出。
队列类
队列的特征:
队列储存有序的项目序列:
队列所能够容纳的项目数有一定的限制;
应当能够创建空队列;
应当能够检查队列是否为空;
应当能够检查队列是否为满的;
应当能够在队尾添加项目;
应当能够从队首删除项目;
应当能够确定队列中项目数。
嵌套结构和类
在类声明中声明的结构、类或枚举被称为是嵌套在类中,其作用于为整个类。这种声明不会创建数据对象,而只是指定了可以在类中使用的类型。如果声明是在类的私有部分进行的,则只能在这个类使用被声明的类型;如果声明是在公有部分进行的,则可以从类的外部通过作用域解析运算符使用被声明的类型。
成员初始化列表的语法
如果Classy是一个类,而mem1,mem2,mem3都是这个类的数据成员,则类构造函数可以使用如下的语法来初始化数据成员:
Classy::Classy(int n, int m) :mem1(n),mem2(0),men3(n*m+2)
{
//...
}
上面的代码将mem1初始化为n,将mem2初始化为0,将mem3初始化为n*m+2
从概念上说,初始化工作是在对象创建时完成的,此时还未执行括号中的任何代码。
请注意以下几点:
这种格式只能用于构造函数;
必须用这种格式来初始化非静态const数据成员;
必须用这种格式来初始化引用数据成员。
数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。
警告:不能将成员初始化列表语法用于构造函数之外的其他类方法。