嵌套类与局部类

news/2025/4/22 1:15:07

一、嵌套类

 

   在一个类的内部定义另一个类,我们称之为嵌套类(nested class),或者嵌套类型。之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用于外围类的实现,且同时可以对用户隐藏该底层实现。
 
 
   虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类,同样,外围类的成员也不属于该嵌套类。嵌套类的出现只是告诉外围类有一个这样的类型成员供外围类使用。并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员的访问也同样如此,它们都遵循普通类所具有的标号访问控制。
 
 
 
   若不在嵌套类内部定义其成员,则其定义只能写到与外围类相同的作用域中,且要用外围类进行限定,不能把定义写在外围类中。例如,嵌套类的静态成员就是这样的一个例子。
 
 
   前面说过,之所以使用嵌套类的另一个原因是达到底层实现隐藏的目的。为了实现这种目的,我们需要在另一个头文件中定义该嵌套类,而只在外围类中前向声明这个嵌套类即可。当然,在外围类外面定义这个嵌套类时,应该使用外围类进行限定。使用时,只需要在外围类的实现文件中包含这个头文件即可。
 

   另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员(假定这些成员是公有的)。类型名是一个typedef名字、枚举类型名、或是一个类名。


实例如下:
 

#ifndef NESTCLASS_H_ 
#define NESTCLASS_H_ 

class A
{
public:
     A();
     ~A();
 
     void operate();
private:
     class B;
     B* m_b;
};
 
#endif 

 
#include "nestclass.h" 
#include <iostream> 
using namespace std;
 
class A::B
{
public:
     B(){}
     ~B(){}
 
     void operate()
     {
         cout<<"B operate!"<<endl;
     }
};
 
A::A()
{
 
}
 
A::~A()
{
 
}
 
void A::operate()
{
    m_b = new B;
    cout<<"A operate!"<<endl;
    m_b->operate();
}

#include "nestclass.h" 

void main()
{
     A a;
     a.operate();
}
 
        在嵌套类的定义被看到之前我们只能声明嵌套类的指针和引用,如上面在A中定义为B m_b而不是B* m_b将会引发一个编译错误。

       关于C++嵌套类的详细用法请参考《C++ Primer 第三版》P551。

 

二、局部类

 

     类也可以定义在函数体内 这样的类被称为局部类(local class), 局部类只在定义它的局部域内可见,与嵌套类不同的是,在定义该类的局部域外没有语法能够引用局部类的成员, 因此,局部类的成员函数必须被定义在类定义中,在实际中,这就把局部类的成员函数的复杂性限制在几行代码中,否则,对读者来说,代码将变得很难理解。 


    因为没有语法能够在名字空间域内定义局部类的成员 ,所以也不允许局部类声明静态数据成员。

     在局部类中嵌套的类可以在其类定义之外被定义,但是,该定义必须出现在包含外围局部类定义的局部域内。在局部域定义中的嵌套类的名字必须由其外围类名限定修饰,在外围类中,该嵌套类的声明不能被省略。例如:

void foo( int val ) 

class Bar { 
public: 
  int barVal; 
  class nested; // 嵌套类的声明是必需的 
}; 
 
// 嵌套类定义 
class Bar::nested { 
  // ... 
}; 
}

 

     外围函数没有特权访问局部类的私有成员,当然,这可以通过使外围函数成为局部类的友元来实现。

    同嵌套类一样,局部类可以访问的外围域中的名字也是有限的,局部类只能访问在外围局部域中定义的类型名、静态变量以及枚举值,例如:

 

int a, val; 
 
void foo( int val ) 

static int si; 
enum Loc { a = 1024, b }; 
 
class Bar { 
public: 
  Loc locVal; // ok; 
  int barVal; 
  void fooBar( Loc l = a ) { // ok: Loc::a 
   barVal = val; // 错误: 局部对象 
   barVal = ::val; // OK: 全局对象 
   barVal = si; // ok: 静态局部对象 
   locVal = b; // ok: 枚举值 
  } 
}; 
// ... 
}

 

     在局部类体内,不包括成员函数定义中的 的名字解析过程是,在外围域中查找出现在局部类定义之前的声明,在局部类的成员函数体内的名字的解析过程是:在查找外围域之前 ,首先直找该类的完整域 。

 
     还是一样,如果先找到的声明使该名字的用法无效,则不考虑其他声明,即使在fooBar() 中使用 val 是错的,编译器也不会找到全局变量val ,除非用全局域解析操作符限定修饰 val,如 ::val 。


https://dhexx.cn/news/show-2510073.html

相关文章

DBA避坑宝典:Oracle运维中的那些事儿

对于Oracle运维中的那些事儿&#xff0c;我的最终目的&#xff1a;不是比谁更惨&#xff0c;而是能够从中吸取经验和教训。 从我的理解来看&#xff0c;我会从下面的几个方面来进行说明DBA运维中的一些事儿。 每个部分都是非常关键的&#xff0c;缺一不可&#xff0c;而且每一部…

再论空指针检测问题

某些C/C编程的书中,曾经提到如何判断指针是否为空的问题.很显然,if (p NULL), if (p 0) 和if(p),都能够完成这一任务,差别在于可读性方面.我们分别加以讨论. 1. if (p NULL) 相当多的文章建议采用,他们中的部分人甚至认为,其他做法都是错误的.这个形式一个变种是 if (NULL …

车联网V2X介绍之:通信芯片

车联网V2X介绍之&#xff1a;通信芯片 参考链接&#xff1a;https://zhuanlan.zhihu.com/p/115276002 目前&#xff0c;我国产业化进程逐步加快&#xff0c;产业链上下游企业已经围绕LTE-V2X形成包括通信芯片、通信模组、终端设备、整车制造、运营服务、测试认证、高精度定位及…

《SQL入门经典(第5版)》一一1.6 问与答

本节书摘来自异步社区出版社《SQL入门经典&#xff08;第5版&#xff09;》一书中的第1章&#xff0c;第1.6节&#xff0c;作者&#xff1a;【美】Ryan Stephens , Ron Plew , Arie D.Jones&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看。 1.6 问与答 SQL入…

看V2X标准之争,美国/欧洲/日本/中国如何布局车联网?

看V2X标准之争&#xff0c;美国/欧洲/日本/中国如何布局车联网&#xff1f; 参考链接&#xff1a;https://www.ednchina.com/news/20170411V2X.html 中国信息通信研究院副主任汤立波博士在近日“智能交通和安全车联网的未来之路”中分享了车联网的整个产业链&#xff0c;以及…

网络序、大端与小端问题

网络序、大端与小端 简单说&#xff0c; 小端就是把低字节存放在低地址&#xff1b; 大端就是把高字节存放在低地址&#xff1b; 为了防止网络传输数据在不同CPU平台上出现字节序不一样的情况&#xff0c; UPD/TCP/IP协议规定&#xff1a;网络字节序采用大端字节序。具体规定为…

V2X主要用到什么技术?

V2X主要用到什么技术? 参考链接:https://www.zhihu.com/question/56755587 主要是两种技术。1、基于802.11的DSRC(Dedicated Short Range Communication)(专用短距离通信)解决方案,使用5.9GHz频段。 美国交通部有计划在2019年之后强制在汽车上安装DSRC模块。有关DSRC的试…

虚拟内存、物理内存、页面文件和任务管理器介绍

虚拟内存、物理内存、页面文件和任务管理器介绍 : 虚拟内存&#xff08;Virtual Memory&#xff09;是Windows管理所有可用内存的方式。 : 对于32位Windows系统&#xff0c;每个进程所用到的虚拟内存地址从0到2^32-1&#xff0c;总容量4GB&#xff0c; : 其中2GB是与操作系统以…

Nginx HTTPS功能部署实践

本文出处&#xff1a;http://oldboy.blog.51cto.com/2561410/1889346 30.1 文档目的 本文目的提高自己文档的写作能力及排版能力,加强上课所讲的内容得以锻炼也方便自己以后查阅特写此文档。 30.2 文档内容 本章内容包括:单向和双向认证的概念、openssl的介绍、Nginx单向ssl的配…

日志抓取方法总结

日志抓取方法总结 一、不在终端上显示日志 ./test >> /dev/null & 二、在后台抓取并保存日志 ./test >> /log/xxx.txt & 三、把 filename 文件里的最尾部的内容显示在屏幕上,并且不断刷新 tail -f filename 会把 filename 文件里的最尾部的内容显示在屏…