09 嵌套类

嵌套类

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

  • 定义嵌套类的目的在于

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

  •   class A
      {
      public:
          class B
          {
          public:
              ...
          private:
              ...
          };
          void f();
      private:
          ...
      }
    
  • attention

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

Example 1. 嵌套类

#include <iostream>
using namespace std;
class c1
{
public:
    int a;
    void foo();
    class c2
    {
    public:
        int a;
        void foo();
    } b;
};
class c3
{
public:
    int a;
    void foo() { a = 3; }
    class
    {
    public:
        int a;
        void foo() { a = 4; }
    } b;
};
void c1::foo()
{
    a = 1;
}
void c1::c2::foo()
{
    a = 2;
}
int main()
{
    class c1 f;
    f.foo();
    f.b.foo();
    cout << f.a << endl;
    cout << f.b.a << endl;
    cout << endl;
    c3 ff;
    ff.foo();
    ff.b.foo();
    cout << ff.a << endl;
    cout << ff.b.a << endl;
    return 0;
}
/*
1
2

3
4
*/
  • 嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,即使这些是private

    • Example 2.nestclass
      image-20211119191743931image-20211119191802795image-20211119191819791
  • 模板中的嵌套

    •   #ifndef __QUEUETP_H__
        #define __QUEUETP_H__
        //模板类
        template <class Item>
        class QueueTP
        {
        private:
            enum
            {
                Q_SIZE = 10
            };
            //嵌套类
            class Node
            {
            public:
                Item item;
                Node *next;
                Node(const Item &i) : item(i), next(0) {}
            };
            Node *front;
            Node *rear;
            int items;
            const int qsize;
            QueueTP(const QueueTP &q) : qsize(0) {}
            QueueTP &operator=(const QueueTP &q) { return *this; }
        
        public:
            QueueTP(int qs = Q_SIZE);
            ~QueueTP();
            bool isEmpty() const { return items == 0; }
            bool isFull() const { return items == qsize; }
            bool queueCount() const { return items; }
            bool enqueue(const Item& item);
            bool dequeue(Item& item);
        };
        
        template <class Item>
        QueueTP<Item>::QueueTP(int qs) : qsize(qs)
        {
            //置为空值指针
            front = rear = 0;
            items = 0;
        }
        template <class Item>
        QueueTP<Item>::~QueueTP()
        {
            Node *temp;
            while (front != 0)
            {
                temp = front;
                front = front->next;
                delete temp;
            }
        }
        template <class Item>
        bool QueueTP<Item>::enqueue(const Item &item)
        {
            if (isFull())
                return false;
            Node *add = new Node(item);
            items++;
            if (front == 0)
            {
                front = add;
            }
            else
            {
                rear->next = add;
            }
            rear = add;
            return true;
        }
        template <class Item>
        bool QueueTP<Item>::dequeue(Item &item)
        {
            if (front == 0)
                return false;
            item = front->item;
            items--;
            Node *temp = front;
            front = front->next;
            delete temp;
            if (items == 0)
                rear = 0;
            return true;
        }
        #endif
      
      #include <iostream>
      #include <string>
      #include "queuetp.h"
      int main()
      {
          using std::cin;
          using std::cout;
          using std::endl;
          using std::string;
          QueueTP<string> cs(5);
          string temp;
          while (!cs.isFull())
          {
              cout << "Please enter your name. You will be serve in the order of arrival. name: " << endl;
              getline(cin, temp);
              cs.enqueue(temp);
          }
          cout << "The queue is full. Processing begins!" << endl;
          while (!cs.isEmpty())
          {
              cs.dequeue(temp);
              cout << "Now processing " << temp << "..." << endl;
          }
          return 0;
      }
      
      image-20211119200116023
  • 局部类

    • 定义在一个函数内部的类,这个类只能在这个函数内部使用
  • 函数是不能嵌套的

    •   int main()
        {
            void foo(){cout<<"Wrong";}
            foo();
        }
        //错误
      
    •   #include <iostream>
        using namespace std;
        int main()
        {
            struct
            {
                void operator()(void)
                {
                    cout << "Hello" << endl;
                }
                int operator()(int a, int b) { return a + b; }
            } foo;
            foo();
            cout << foo(1, 2);
            return 0;
        }
        /*
        Hello
        3
        */
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值