嵌套类和局部类

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了嵌套类和局部类相关的知识,希望对你有一定的参考价值。

嵌套类和局部类在工作中极少使用,且均可在设计上替代,这里仅做简要介绍。
1)局部类
局部类就是将类定义在函数中。形如:
int val = 100;
void foo(int val)

struct Bar


;

class Bar::InsideClass//定义InsideClass类


;


2)嵌套类
嵌套类就是将一个类定义在另一个类中。形如:
class Interface

public:
? ?virtual void Fun() = 0; ?
;
?
template <class T, class P>
Interface* Person(const T& obj, const P& arg)

? ? int x;
? ?class Local : public Interface
? ?
? ?public:
? ? ? Local(const T& obj, const P& arg)
? ? ? ? ?: obj(obj), arg(arg)
? ? ? virtual void Fun()
? ? ?
? ? ? ? ?
? ? ?
? ?private:
? ? ? T a;
? ? ? P b;
? ?;
? ?return new Local(obj, arg);

嵌套类必须声明在类的内部,但是可以定义在类的内部或者外部。在外层类之外定义一个嵌套类时,必须以外层类的名字限定嵌套类的名字。
?嵌套类的名字只在外围类可见。
?类的私有成员只有类的成员和友元可以访问,因此外围类不可以访问嵌套类的私有成员。嵌套类可以访问外围类的成员(通过对象、指针或者引用)。
一个好的嵌套类设计:嵌套类应该设成私有。嵌套类的成员和方法可以设为?public?。
嵌套类可以直接访问外围类的静态成员、类型名(?typedef?)、枚举值。
?

?

(内部类与外部类)
1.1?作用域
嵌套类的声明位置决定了嵌套类的作用域,即它决定了程序的那部分可以创建嵌套类的对象。

如果嵌套类声明在一个类的私有部分,则只有嵌套类的外部类可以知道它。上面的类就是这种情况。

如果嵌套类声明在一个类的保护部分,对于后者是可见的,对于外界是不可见的。派生类知道该嵌套类,并且可以直接创建这种类型的对象。

如果嵌套类声明在一个类的公有部分,则允许后者,后者的派生类以及外部世界使用。然后在外部使用时,必须加上外部类的外部类作用域限制符,如:?使用NestedClass 时,应该这样定义 OutClass::NestedClass nestedInstance.

嵌套结构和枚举的作用域于此相同。许多程序员使用公有的枚举提供客户使用的类常量。

下面表格总结了,嵌套类、结构、枚举的作用域特征。

1.2 访问权限
? ? 在外部类中声明嵌套类并没有赋予外部类任何对嵌套类的访问权限,也没有赋予任何嵌套类对于外部类的访问权限。与一般类的访问控制相同(私有,公有,保护)。

?
局部类
类可以定义在某个函数的内部,这样的类被称为局部类,局部类定义的类型只在定义它的作用域内可见。
局部类不能使用函数作用域中的变量。
局部类已经封装在函数作用域中,通过信息隐藏进一步封装就显得没什么必要了。
可以在局部类的内部再嵌套一个类,此时,嵌套类的定义可以出现在局部类之外且与局部类相同的作用域中。

(c++不能在函数中定义函数。c++在类中定义的函数也就是成员函数。)这个类以及由它创建的对象,都局限在该函数作用域中;必须在类内实现所有的成员函数,不能拿到类外。因为函数是不可以嵌套定义的;若类内含有静态数据成员,必须在该函数外初始化;类内不可含有静态函数成员;类中不可使用包裹它的函数所定义的除静态外的局部变量。

c++内部类与java内部类的区别就是:
c++的内部类对象没有外部类对象的指针,不能访问外部类对象的非静态成员;java的非静态内部类对象有外部类对象的指针,能访问外部类对象的非静态成员。

1 局部类Demo 示例
int a;
  void fun()
  
  static int s;
  class A
  
    public:
    void init(int i) s = i;
  ;
  A m;
  m.init(10);
  

2 ?局部类的另一个用途是用来实现类型转化
class Interface

public:
? ?virtual void Fun() = 0; ?
;
?
template <class T, class P>
Interface* MakeAdapter(const T& obj, const P& arg)

? ? int x;
? ?class Local : public Interface
? ?
? ?public:
? ? ? Local(const T& obj, const P& arg)
? ? ? ? ?: obj(obj), arg(arg)
? ? ? virtual void Fun()
? ? ?
? ? ? ? ? x = 100;
? ? ? ? ?obj.Call(arg);
? ? ?
? ?private:
? ? ? T obj;
? ? ? P arg
;
? ?;
? ?return new Local(obj, arg);

.内嵌类
是在类体内定义的又一个类。外面的类叫外围类。这个类以及由它创建的对象,都局限在外层类作用域中;

外界能否使用内层类,全在于访问权限;若能使用,定要以外围类::内层类格式来用;

是类组合演化的又一种类间关系,即组合或聚集成员不是产生于其它类,而是产生于内层类;内层类的成员函数,可以在类内实现,也可以在外层类之外实现;

内层类的成员函数对外围类的成员没有访问权,反之亦然

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

1 下面是一个嵌套类的例子
class A
  
  ?public:
    class B
    
    public:
      …
    private:
      …
    ;
    void f();
    private:
    int a;
  
其中,类B是一个嵌套类,类A是外围类,类B定义在类A的类体内。

2 ?对嵌套类的若干说明:

1、从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类的作用域内使用该类名时,需要加名字限定。
2、从访问权限的角度来看,嵌套类名与它的外围类的对象成员名具有相同的访问权限规则。不能访问嵌套类的对象中的私有成员函数,也不能对外围类的私有部分中的嵌套类建立对象。
3、嵌套类中的成员函数可以在它的类体外定义。
4、嵌套类中说明的成员不是外围类中对象的成员,反之亦然。嵌套类的成员函数对外围类的成员没有访问权,反之亦然。国此,在分析嵌套类与外围类的成员访问关系时,往往把嵌套类看作非嵌套类来处理。

上述的嵌套类可写成如下格式:

class A
  
  public:
    void f();
  private:
    int a;
  ;
?
    class B
  
    public:
    …
  private:
    …
  ;
由引可见,嵌套类仅仅是语法上的嵌入。

5、在嵌套类中说明的友元对外围类的成员没有访问权。
6、如果嵌套类比较复杂,可以只在外围类中对嵌套类进行说明,关于嵌套的详细的内容可在外围类体外的文件域中进行定义。

以上是关于嵌套类和局部类的主要内容,如果未能解决你的问题,请参考以下文章

30根据官方教程详解嵌套类内部类静态嵌套类局部类匿名类 ...

Effective Java2读书笔记-类和接口

java之内部类精选

内部类中新建外部类,个人觉得行不通(会死循环嵌套),但是遇到了一个程序就是这样写的。 请高手解决~

Java内部类详解(含:成员内部类局部内部类匿名内部类静态内部类)

静态内部类(静态嵌套类或嵌套类)