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

 更新时间:2016年01月22日 16:27:56   投稿:goldensun  
这篇文章主要介绍了C++编程中的嵌套类的声明与其中的函数使用,嵌套类即在一个类的范围内声明和编写另一个类,需要的朋友可以参考下

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

// 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++线程亲和性优化指南分享

    C++线程亲和性优化指南分享

    线程亲和性通过绑定线程到特定CPU核心,减少迁移开销,提升缓存命中率和性能,适用于多核、NUMA架构,实现方式包括Linux的pthread库和Windows的API,需注意负载均衡、超线程及系统拓扑,建议结合工具验证效果
    2025-09-09
  • C++中rapidjson将map转为json的方法

    C++中rapidjson将map转为json的方法

    今天小编就为大家分享一篇关于C++中rapidjson将map转为json的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-04-04
  • C语言深入讲解之从函数栈帧角度理解return关键字

    C语言深入讲解之从函数栈帧角度理解return关键字

    在C语言中,一般情况下函数的返回值是通过函数中的return语句来实现的,每调用一次return语句只能从函数中返回一个值,这篇文章主要给大家介绍了关于C语言从函数栈帧角度理解return关键字的相关资料,需要的朋友可以参考下
    2021-09-09
  • C++字符串的截取问题

    C++字符串的截取问题

    这篇文章主要介绍了C++字符串的截取问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • C++实现OpenCV方框滤波的代码

    C++实现OpenCV方框滤波的代码

    这篇文章主要介绍了C++ OpenCV方框滤波的实现,方框滤波是均值滤波的一种形式,今天通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2021-10-10
  • C++中赋值初始化和直接初始化的区别

    C++中赋值初始化和直接初始化的区别

    赋值初始化和直接初始化虽然常常产生相同的结果,但在某些情况下它们有不同的含义和行为,本文主要介绍了C++中赋值初始化和直接初始化的区别,具有一定的参考价值,感兴趣的可以了解一下
    2025-04-04
  • C语言中预处理命令的使用

    C语言中预处理命令的使用

    C语言预处理是编程中非常重要的一个环节,通过预处理指令和预处理器的一些特性,本文主要介绍了C语言中预处理命令的使用,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • OpenCV+Qt实现图像处理操作工具的示例代码

    OpenCV+Qt实现图像处理操作工具的示例代码

    这篇文章主要介绍了利用OpenCV+Qt实现图像处理操作工具,可以实现雪花屏、高斯模糊、中值滤波、毛玻璃等操作,感兴趣的可以了解一下
    2022-08-08
  • C/C++代码操作MySQL数据库详细步骤

    C/C++代码操作MySQL数据库详细步骤

    这篇文章主要给大家介绍了关于C/C++代码操作MySQL数据库的相关资料,通过文中的这些示例,我们可以连接到MySQL数据库,并执行常见的数据库操作,如创建表、插入数据和查询数据,需要的朋友可以参考下
    2023-12-12
  • C++之list的使用与模拟实现过程

    C++之list的使用与模拟实现过程

    本文简述C++ list容器,其基于双向循环链表,支持高效插入删除,迭代器失效仅影响被删除节点,模拟实现时通过封装节点和迭代器,对比list与vector的特性差异,如随机访问、空间利用率及适用场景
    2025-10-10

最新评论