zoukankan      html  css  js  c++  java
  • C++ 嵌套类使用(一)

    一、嵌套类

     

       在一个类的内部定义另一个类,我们称之为嵌套类(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  
    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 。

  • 相关阅读:
    java进度条
    获取程序运行环境
    struts2学习笔记(二) 初识Struts2
    HttpComponents入门解析
    C#编码规范
    js实现GBK编码
    struts2学习笔记(一) MVC模式
    mysql数据库操作类
    java类装载器原理
    [Study Note] NHibernate in Action 20100729
  • 原文地址:https://www.cnblogs.com/lidabo/p/3772477.html
Copyright © 2011-2022 走看看