c++ primer plus 第15章友,异常和其他:嵌套类15.2

时间:2024-07-07 06:57:24

c++ primer plus 第15章友,异常和其他:嵌套类15.2

提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
例如:c++ primer plus 第15章友,异常和其他:嵌套类15.2


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • c++ primer plus 第15章友,异常和其他:嵌套类15.2
  • 嵌套类15.2


嵌套类15.2

在 C++中,可以将类声明放在另一个类中。在另一个类中声明的类被称为嵌套类(nested class),它通过提供新的类型类作用域来避免名称混乱。包含类的成员函数可以创建和使用被嵌套类的对象:而仅当声明位于公有部分,才能在包含类的外面使用嵌套类,而且必须使用作用域解析运算符(然而,旧版本的 C++不允许嵌套类或无法完全实现这种概念)。
对类进行嵌套与包含并不同。包含意味着将类对象作为另一个类的成员,而对类进行嵌套不创建类成
员,而是定义了一种类型,该类型仅在包含嵌套类声明的类中有效。对类进行嵌套通常是为了帮助实现另一个类,并避免名称冲突。Queue 类示例(第 12 章的程序清单 12.8)嵌套了结构定义,从而实现了一种变相的嵌套类:

class ueue
private :
//class scope definitions//Node is a nested structure definition local to this class
struct Node{Item item;struct Node *next;}
};
 

由于结构是一种其成员在默认情况下为公有的类,所以 Node 实际上是一个嵌套类,但该定义并没有充分利用类的功能。具体地说,它没有显式构造函数,下面进行补救。
首先,找到 Queue 示例中创建 Node对象的位置。从类声明(程序清单 11.10)和方法定义(程序清单 12.11)可知,唯一创建了 Node 对象的地方是enqueue()方法:

bool Queue::enqueue(constItem &item)
{
if (isfull())
 return false;
Node *add =new Node;//create node//on failure,new throws std::bad alloc exception
add->item =item;//set node pointers
add->next=NULL;
...
}

上述代码创建 Node 后,显式地给Node 成员赋值,这种工作更适合由构造函数来完成。知道应在什么地方以及如何使用构造函数后,便可以提供一个适当的构造函数定义:class Queue

class scope definitions
// Node is a nested class definition local to this class
class Node
{
public:
Item item;
Node *next;
Node(const Item&i):item(i),next(0){}
};

该构造函数将节点的item 成员初始化为i,并将next 指针设置为0,这是使用C++编写空值指针的方法之一(使用 NULL时,必须包含一个定义NULL的头文件;如果您使用的编译器支持 C++11,可使用nullptr)。由于使用 Queue 类创建的所有节点的 next 的初始值都被设置为空指针,因此这个类只需要该构造函数。
接下来,需要使用构造函数重新编写enqueue():

bool Queue::enqueue(const Item & item)
if (isfu11())
return false:
Node *add =new Node(item);//create,initialize node/on failure,new throws std::bad alloc exception

. …
这使得 enqueue()的代码更短,也更安全,因为它自动进行初始化,无需程序员记住应做什么。这个例子在类声明中定义了构造函数。假设想在方法文件中定义构造函数,则定义必须指出 Node 类是在 Queue 类中定义的。这是通过使用两次作用域解析运算符来完成的:

Queue::Node::Node(const Item&i):item(i)next(0)