频道栏目
首页 > 程序开发 > 软件开发 > C++ > 正文
第18章 特殊工具与技术(10)
2012-01-09 08:45:10           
收藏   我要投稿
上一篇:/kf/201201/116156.html

18.4 嵌套类
可以在另一个类内部定义一个类,这样的类是嵌套类(nested class),也称为嵌套类型(nested type)。嵌套类最常用于定义执行类。
嵌套类是独立的类,基本上与它们的外围类不相关,因此,外围类与嵌套类的对象是相互独立的。嵌套类型的对象不具有外围类所定义的成员,同样,外围类的成员也不具备嵌套类所定义的成员。
嵌套类的名字在其外围类的作用域中可见,但在其他类作用域或定义外围类的作用域中不可见。嵌套类的名字将不会与另一作用域中声明的名字冲突。
嵌套类可以具有与非嵌套类相同种类的成员。像其任何他类一样,嵌套类使用访问标号控制对自己成员的访问。成员可以声明为public、private或protected。外围类对嵌套类的成员没有特殊访问权,并且嵌套类对其外围类的成员也没有特殊访问权。
嵌套类定义了其外围类的一个类型成员。像任何其他成员一样,外围类决定对这个类型的访问。在外围类的public部分定义的嵌套类定义了可在任何地方使用的类型,在外围类的protected部分定义的嵌套类定义了只能由外围类、友元或派生类访问的类型,在外围类的private部分定义的嵌套类只能被外围类或其友元访问的类型。
18.4.1 嵌套类的实现

namespace MyNamespace 

    template<class T>  
    class Queue{ 
    private: 
        struct QueueItem{ 
            QueueItem(const T&); 
            T item; 
            QueueItem *next; 
        }; 
        QueueItem *head; 
        QueueItem *tail; 
    }; 

1. 嵌套在类模板内部的类是模板
2. 定义嵌套类的成员
在其类外部定义的嵌套类成员,必须定义在定义外围类的同一作用域中。在其类外部定义的嵌套类的成员,不能定义在外围类内部,嵌套类的成员不是外围类的成员。

namespace MyNamespace 

    template<class T>  
    class Queue{ 
    private: 
        struct QueueItem{ 
            QueueItem(const T&); 
            T item; 
            QueueItem *next; 
        }; 
        QueueItem *head; 
        QueueItem *tail; 
    }; 
 
 
    template <class T> 
    Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){ 
    } 

3. 在外围类外部定义嵌套类
嵌套类支持外围类的实现细节。我们可能希望防止外围类的用户看见嵌套类的实现代码。正如可以在类定义体外部定义嵌套类的成员一样,我们也可以在外围类定义体的外部定义整个嵌套类。

namespace MyNamespace 

    template<class T>  
    class Queue{ 
    private: 
        struct QueueItem; 
        QueueItem *head; 
        QueueItem *tail; 
    }; 
 
 
    template<class T> 
    struct Queue<T>::QueueItem{ 
        QueueItem(const T&); 
        T item; 
        QueueItem *next; 
    }; 
 
 
    template <class T> 
    Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){ 
    } 

在看到类定义体外部定义的嵌套类的实际定义之前,该类是不完全类型,应用所有使用不完全类型的常规规则。
4. 嵌套类静态成员定义

namespace MyNamespace 

    template<class T>  
    class Queue{ 
    private: 
        struct QueueItem; 
        QueueItem *head; 
        QueueItem *tail; 
    }; 
 
 
    template<class T> 
    struct Queue<T>::QueueItem{ 
        QueueItem(const T&); 
        T item; 
        QueueItem *next; 
        static int static_mem; 
    }; 
 
 
    template<class T> 
    int Queue<T>::QueueItem::static_mem=1; 
 
 
    template <class T> 
    Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){ 
    } 

5. 使用外围类的成员
外围作用域的对象与其嵌套类型的对象之间没有联系。

namespace MyNamespace1 

    template<class T>  
    class Queue{ 
    private: 
        struct QueueItem; 
        QueueItem *head; 
        QueueItem *tail; 
        void *pop(); 
    }; 
 
 
    template<class T> 
    struct Queue<T>::QueueItem{ 
        QueueItem(const T&); 
        T item; 
        QueueItem *next; 
        static int static_mem; 
    }; 
 
 
    template<class T> 
    int Queue<T>::QueueItem::static_mem=1; 
 
 
    template<class T> 
    Queue<T>::QueueItem::QueueItem(const T &t):item(0),next(0){ 
    } 
 
 
    template<class T> 
    void *Queue<T>::pop() 
    { 
        QueueItem *p=head; 
        head=head->next; 
        delete p; 
    } 

6. 使用静态成员或其他类型的成员
嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,当然,引用外围类作用域之外的类型名或静态成员,需要作用域确定操作符。
7. 嵌套模板的实例化
实例化外围类模板的时候,不会自动实例化类模板的嵌套类。像任何成员函数一样,只有当在需要完整类类型的情况下使用嵌套类本身的时候,才会实例化嵌套类。
18.4.2 嵌套类作用域中的名字查找
对嵌套类中所用名字的名字查找在普通类的名在查找之前进行,现在唯一的区别是可能要查找一个或多个外围类作用域。
当处理类成员处理时,所用的任意名字必须出现在使用之前。当处理定义的时候,整个嵌套类和外围类均在作用域中。
使用作用域操作符控制名字查找
可以使用作用域操作符访问外围作用域。

摘自 xufei96的专栏
点击复制链接 与好友分享!回本站首页
相关TAG标签 工具 技术
上一篇:第18章 特殊工具与技术(9)
下一篇:工作代码片段-boost::asio
相关文章
图文推荐
文章
推荐
点击排行

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站