C++嵌套类及对外围类成员变量的访问

  在一个类中定义的类称为嵌套类,定义嵌套类的类称为外围类。

  定义嵌套类的目的在于隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。这样可以提高类的抽象能力,并且强调了两个类(外围类和嵌套类)之间的主从关系。下面是一个嵌套类的例子:   

class A
 {
  public:
   class B
   {
   public:
     …
   private:
     …
   };
  void f();
 private:
   int a;
 }

  

其中,类B是一个嵌套类,类A是外围类,类B定义在类A的类体内。

  对嵌套类的若干说明:

  1、从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类的作用域内使用该类名时,需要加名字限定。

  2、从访问权限的角度来看,嵌套类名与它的外围类的对象成员名具有相同的访问权限规则。不能访问嵌套类的对象中的私有成员函数,也不能对外围类的私有部分中的嵌套类建立对象。

  3、嵌套类中的成员函数可以在它的类体外定义。

  4、嵌套类中说明的成员不是外围类中对象的成员,反之亦然。嵌套类的成员函数对外围类的成员没有访问权,反之亦然。国此,在分析嵌套类与外围类的成员访问关系时,往往把嵌套类看作非嵌套类来处理。这样,上述的嵌套类可写成如下格式:

  class A
  {
  public:
    void f();
  private:
    int a;
  };

  class B
  {
  public:
    …
  private:
    …
  };

  由引可见,嵌套类仅仅是语法上的嵌入。

  5、在嵌套类中说明的友元对外围类的成员没有访问权。

  6、如果嵌套类比较复杂,可以只在外围类中对嵌套类进行说明,关于嵌套的详细的内容可在外围类体外的文件域中进行定义。

7、嵌套类可以访问外围类的静态成员变量,即使它的访问权限是私有的。

  但是,如果一定要让嵌套类访问外围类,我们要采取什么样的办法?实际上实现的方法应该有很多种,这里介绍一种参见com实现中实现内嵌类访问外部类数据成员中所使用的方式,具体见《COM本质论》。

//嵌套类访问外围类中的成员变量

class GH_A{
  const static int s_data = 20;
public:
  int task_id;

  class GH_B
  {
  public:
    int attribute;
    GH_A* parent;
    GH_B(){
    attribute = 5;
    parent = (GH_A*)((char*)this-offsetof(GH_A,gh_b));
    printf("外围类的private型静态变量:%d\n",s_data);
    }
  } gh_b;
};

  

//嵌套类访问外围类成员变量的示例

  GH_A aaaa;
  aaaa.gh_b.parent->task_id = 16;
  printf("外围类成员变量值被嵌套类访问并修改之后的值:%d\n",aaaa.task_id);
  aaaa.task_id = aaaa.gh_b.attribute;
  printf("嵌套类访问到外围类成员变量值:%d\n",aaaa.gh_b.parent->task_id);

  

输出结果:

这里,我们用到一个C++库函数,原型是:
size_t offsetof(
      structName,
      memberName
);

以下是MSDN上的一些介绍:

Parameters

structName

Name of the parent data structure.

memberName

Name of the member in the parent data structure for which to determine the offset.

Return Value

offsetof returns the offset in bytes of the specified member from the beginning of its parent data structure. It is undefined for bit fields.

 

C++嵌套类及对外围类成员变量的访问的更多相关文章

  1. (转载)php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗?

    (转载)http://s.yanghao.org/program/viewdetail.php?i=184313 php的类中可以不定义成员变量,直接在构造方法中使用并赋值吗? class block ...

  2. Java中变量之局部变量、本类成员变量、父类成员变量的访问方法

    变量:局部变量.本类成员变量.父类成员变量 如何访问:如果变量名相同,则采用就近原则,哪个变量离所要调用的访问最近,那就么就输出,优先顺序为:局部变量 > 本类成员变量 > 父类成员变量 ...

  3. Objective-C 成员变量的访问修饰即成员变量可见性解析

    总体来说Objective-C的访问成员变量可见性和C++基本一样,只是多了个@package. 以下是详细说明: 例子: @interface CTPerson : NSObject { @priv ...

  4. 继承时,当父子类都具有相同的成员变量,默认情况下是直接调用子类的成员变量,当要调用父类的成员变量则需要使用super关键之

    package day02; public class Person { String name="fl"; }class Car{ }class Student extends ...

  5. 深入理解PHP内核(十四)类的成员变量及方法

    原文链接:http://www.orlion.ga/1237/ 类的成员变量在PHP中本质是一个变量,只是这些变量都归属于某个类,并且给这些变量是有访问控制的. 类的成员方法在PHP中本质是一个函数, ...

  6. 福利->KVC+Runtime获取类/对象的属性/成员变量/方法/协议并实现字典转模型

    我们知道,KVC+Runtime可以做非常多的事情.有了这个,我们可以实现很多的效果. 这里来个福利,利用KVC+Runtime获取类/对象的所有成员变量.属性.方法及协议: 并利用它来实现字典转模型 ...

  7. 对Objective-C相关的类、方法、属性、成员变量介绍

    类的定义@interface FirstClass :NSObject@end//@interface表示声明的是一个类,“:”表示继承关系,@end类的结束类的实现@implementation F ...

  8. Objective-C类成员变量深度剖析

    目录 Non Fragile ivars 为什么Non Fragile ivars很关键 如何寻址类成员变量 真正的“如何寻址类成员变量” Non Fragile ivars布局调整 为什么Objec ...

  9. 测试 Java 类的非公有成员变量和方法

    引言 对于软件开发人员来说,单元测试是一项必不可少的工作.它既可以验证程序的有效性,又可以在程序出现 BUG 的时候,帮助开发人员快速的定位问题所在.但是,在写单元测试的过程中,开发人员经常要访问类的 ...

随机推荐

  1. 15、python之导入模块

    一.什么是模块? 模块本质是一个py文件,我们可以通过关键字import将py文件对象导入到当前名称空间. 二.导入模块 1.import module 2.from module import ob ...

  2. 25-IHostEnvironment和 IApplicationLifetime介绍

    //类似 global.ashx的application事件的实现1-Startup类中 public void Configure(IApplicationBuilder app, IHosting ...

  3. Android 内嵌 HTML5 并进行交互

    Android与HTML5的交互主要是两个部分, 与HTML5的交互以及与JavaScript的交互, 与HTML5的交互可以通过注册onclick事件转化为与JavaScript的交互 Androi ...

  4. Android stadio 插件推荐--ok gradle

    今天发现了一个好玩的插件,对于想要知道依赖怎么写的同学很有帮助. 写这篇文章的意义在于,以后我忘了的话,可以自己在博客中找到. 上地址: https://github.com/scana/ok-gra ...

  5. centos使用--开机启动

    centos6.8 1.利用 chkconfig 来配置启动级别 在CentOS或者RedHat其他系统下,如果是后面安装的服务,如httpd.mysqld.postfix等,安装后系统默认不会自动启 ...

  6. 《Cracking the Coding Interview》——第5章:位操作——题目2

    2014-03-19 05:47 题目:给定一个double型浮点数,输出其二进制表示,如果不能在32个字符内完成输出,则输出“ERROR”. 解法:如果你熟悉IEEE754标准,应该知道double ...

  7. Python import与from import使用

    Python程序可以调用一组基本的函数(即内建函数),比如print().input()和len()等函数.Python本身也内置一组模块(即标准库).每个模块都是一个Python程序,且包含了一组相 ...

  8. sql的nvl()函数

    一NVL函数是一个空值转换函数 NVL(表达式1,表达式2) 如果表达式1为空值,NVL返回值为表达式2的值,否则返回表达式1的值. 该函数的目的是把一个空值(null)转换成一个实际的值.其表达式的 ...

  9. python 学习分享-socketserver

    SocketServer内部使用 IO多路复用 以及 “多线程” 和 “多进程” ,从而实现并发处理多个客户端请求的Socket服务端.即:每个客户端请求连接到服务器时,Socket服务端都会在服务器 ...

  10. ASP.NET Core [3]:进入HttpContext的世界(笔记)

    原文链接:http://www.cnblogs.com/RainingNight/p/httpcontext-in-asp-net-core.html HttpContext是ASP.NET中的核心对 ...