详解C++编程中的嵌套类的声明与其中的函数使用

所属分类: 软件编程 / C 语言 阅读数: 82
收藏 0 赞 0 分享

可以在一个类的范围内声明另一个类。这样的类称为“嵌套类”。 嵌套类被视为在封闭类的范围内且可在该范围内使用。若要从嵌套类的即时封闭范围之外的某个范围引用该类,则必须使用完全限定名。
下面的示例演示如何声明嵌套类:

// nested_class_declarations.cpp
class BufferedIO
{
public:
  enum IOError { None, Access, General };

  // Declare nested class BufferedInput.
  class BufferedInput
  {
  public:
   int read();
   int good()
   {
     return _inputerror == None;
   }
  private:
    IOError _inputerror;
  };

  // Declare nested class BufferedOutput.
  class BufferedOutput
  {
   // Member list
  };
};

int main()
{
}

在 BufferedIO::BufferedInput 中声明 BufferedIO::BufferedOutput 和 BufferedIO。这些类名称在类 BufferedIO 的范围外不可见。但是,BufferedIO 类型的对象不包含 BufferedInput 或 BufferedOutput 类型的任何对象。
嵌套类只能从封闭类中直接使用名称、类型名称,静态成员的名称和枚举数。若要使用其他类成员的名称,您必须使用指针、引用或对象名。
在前面的 BufferedIO 示例中,枚举 IOError 可由嵌套类中的成员函数、BufferedIO::BufferedInput 或 BufferedIO::BufferedOutput 直接访问,如函数 good 中所示。
注意
嵌套类仅在类范围内声明类型。它们不会导致创建嵌套类的包含对象。前面的示例声明两个嵌套类,但未声明这些类类型的任何对象。
在将类型名称与前向声明一起声明时,会引发嵌套类声明的范围可见性的异常。在这种情况下,由前向声明声明的类名在封闭类的外部可见,其范围定义为最小的封闭非类范围。例如:

// nested_class_declarations_2.cpp
class C
{
public:
  typedef class U u_t; // class U visible outside class C scope
  typedef class V {} v_t; // class V not visible outside class C
};

int main()
{
  // okay, forward declaration used above so file scope is used
  U* pu;

  // error, type name only exists in class C scope
  u_t* pu2; // C2065

  // error, class defined above so class C scope
  V* pv; // C2065

  // okay, fully qualified name
  C::V* pv2;
}

嵌套类中的访问权限
将一个类嵌入另一个类中不会为嵌入类的成员函数提供特殊访问权限。同样,封闭类的成员函数不具有对嵌套类的成员的特殊访问权限。
嵌套类中的成员函数
在嵌套类中声明的成员函数可在文件范围中定义。前面的示例可能已编写:

// member_functions_in_nested_classes.cpp
class BufferedIO
{
public:
  enum IOError { None, Access, General };
  class BufferedInput
  {
  public:
    int read(); // Declare but do not define member
    int good(); // functions read and good.
  private:
    IOError _inputerror;
  };

  class BufferedOutput
  {
    // Member list.
  };
};
// Define member functions read and good in
// file scope.
int BufferedIO::BufferedInput::read()
{
  return(1);
}

int BufferedIO::BufferedInput::good()
{
  return _inputerror == None;
}
int main()
{
}

在前面的示例中,qualified-type-name 语法用于声明函数名称。声明:

BufferedIO::BufferedInput::read()

表示“作为 read 类(位于 BufferedInput 类的范围中)的成员的 BufferedIO 函数。” 由于此声明使用 qualified-type-name 语法,因此以下形式的构造是可能的:

typedef BufferedIO::BufferedInput BIO_INPUT;

int BIO_INPUT::read()

上述声明与前一个声明等效,但它使用了 typedef 名称来代替类名称。
嵌套类中的友元函数
嵌套类中声明的友元函数被认为是在嵌套类而不是封闭类的范围内。因此,友元函数未获得对封闭类的成员或成员函数的特定访问权限。如果需要使用在友元函数中的嵌套类中声明的名称,并且友元函数是在文件范围内定义的,请使用限定的类型名称,如下所示:

// friend_functions_and_nested_classes.cpp

#include <string.h>

enum
{
  sizeOfMessage = 255
};

char *rgszMessage[sizeOfMessage];

class BufferedIO
{
public:
  class BufferedInput
  {
  public:
    friend int GetExtendedErrorStatus();
    static char *message;
    static int messageSize;
    int iMsgNo;
  };
};

char *BufferedIO::BufferedInput::message;
int BufferedIO::BufferedInput::messageSize;

int GetExtendedErrorStatus()
{
  int iMsgNo = 1; // assign arbitrary value as message number

  strcpy_s( BufferedIO::BufferedInput::message,
       BufferedIO::BufferedInput::messageSize,
       rgszMessage[iMsgNo] );

  return iMsgNo;
}

int main()
{
}

以下代码演示声明为友元函数的函数 GetExtendedErrorStatus。在文件范围内定义的函数中,将消息从静态数组复制到类成员中。请注意,GetExtendedErrorStatus 的更佳实现是将其声明为:

int GetExtendedErrorStatus( char *message )

利用前面的接口,许多类可以通过传递要复制错误消息的内存位置来使用此函数的服务。

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多