C++嵌套類

嵌套類就是在一個類(能夠稱爲外圍類)中又定義一個類,如:函數


class A{
    int a;
    class B{int b;};
};
/* A就是外圍類
 * B就是嵌套類 */


嵌套類與外圍類相互獨立

這個主要體如今兩個方面:spa

  • 嵌套類對象中不會含有外圍類的成員,外圍類的對象也不會含有嵌套類的成員,如:A a1,B b1;則a1中不會有B::b這個成員,b1中也不會有A::a這個成員code

  • 嵌套類對外圍類成員的訪問並無特殊權限,也是隻能訪問外圍類的public成員,外圍類對嵌套類成員的訪問也是如此對象

嵌套類是外圍類的類型成員

因此具備數據成員與函數成員的性質:
get

  • 定義在外圍類public區域的嵌套類能夠在程序的任何地方使用編譯器

  • 定義在外圍類protected區域的嵌套類僅能在外圍類及其子類以及友元中使用io

  • 定義在外圍類private區域的嵌套類僅能在外圍類及其友元中使用編譯


#include <stdio.h>

class A{
friend int main(int argc,char *argv[]);
protected:
	class B{};
};

int main(int argc,char *argv[]){
	A::B b;
    /* main是A的友元函數,因此可使用B類類型
     * 使用B類類型須要加上A限定符,由於B是A的靜態成員嘛.. */
	return 0;
}


嵌套類與模板

  • 若外圍類是模板類,則其內部類也隱式的是模板類,但因爲內部類並無用'template<..>'修飾,因此相似'內部類名<Type>'是非法的!!模板

    • 事實上只要肯定了外圍類的模板形參,則內部類內部使用的模板形參也即肯定了.因此沒有必要出現'內部類<Type>'class

template<typename ElemT>
class Queue{
struct  _QueueItem{
    ElemT               _data;/* 使用模板形參 ElemT 定義數據 */
    _QueueItem          *_next;
};
public:
    /** value_type 也是 Queue 的類型成員. */
    typedef     ElemT       value_type;
private:
    _QueueItem  *_head;    /* 並非 _QueueItem<ElemT> */
    _QueueItem  *_tail;
};
template<typename Type>
inline const char* getTypeName( const Type & )  { return typeid(Type).name(); }

#define PrintType(var)      Println(#var ": %s",getTypeName(var));

int main( int argc,char *argv[] ){
    Queue<int>  i;
    i._head=new Queue<int>::_QueueItem; /* 並非 Queue<int>::_QueueItem<int> */

    PrintType(i._head);
    PrintType(i._tail);
    PrintType(i._head->_next);
    Println("_QueueItem<int>*: %s",typeid(Queue<int>::_QueueItem*).name());
    PrintType(i._head->_data);
}
/* --- 程序輸出 --- */
i._head: PN5QueueIiE10_QueueItemE
i._tail: PN5QueueIiE10_QueueItemE
i._head->_next: PN5QueueIiE10_QueueItemE
_QueueItem<int>*: PN5QueueIiE10_QueueItemE
i._head->_data: i

  • 能夠看出 _head,_tail,_head->_next 的類型爲: _QueueItem<int*> 類型

  • _head->_data 的類型爲 int 類型

類外定義內部類的成員


/* A.h */
#ifndef AAAA_H_
#define AAAA_H_

class A{
public:
	class B{
		static int a;
	public:
		B();
		void print();
	};

private:
	static int a;
public:
	A();
	void print();
};

#endif

/* A.cc */
#include "A.h"
#include "stdio.h"

int A::a=33;
int A::B::a=77;

A::A(){ ; }

void A::print(){ printf("A\n"); return ; }
/* 與常規類的外部定義也是同樣的,只不過對於內部類的訪問須要外部類限定符
 * 由於內部類是外部類的類型成員 */
A::B::B(){ ; }

void A::B::print(){ printf("B\n"); return ; }


類外定義內部類

將整個內部類都放在類的外部進行定義,如:


/*
 * A.h
 *
 *  Created on: 2014年1月15日
 *      Author: Dreamlove
 */


#ifndef AAAA_H_
#define AAAA_H_

class A{
public:
	class B;
private:
	static int a;
	B *b;
public:
	A();
	void print();
};

class A::B{
	static int a;
public:
	B();
	void print();
};


#endif

要注意如下:


  • 因爲在A中只是前沿聲明瞭B,因此B是不徹底類型!不能使用B來定義對象(由於B是不徹底類型,因此編譯器不知道爲B分配多少字節的空間);

  • 內部類的完整定義必需要在外部類的完整定義下面,而且內部類名以前要有外部類名來限定,也能夠把內部類與外部類的定義分別放在兩個文件中:


/* A.h */ 
#ifndef AAAA_H_
#define AAAA_H_

class A{
public:
    class B;
private:
    static int a;
    B *b;
public:
    A();
    void print();
};

/* B.h */
#ifndef    BBBB_H_
#define    BBBB_H_

#include "A.h"
/* 由於外圍類的完整定義必需要在內部類以前 */
class A::B{
    static int a;
public:
    B();
    void print();
};

#endif
相關文章
相關標籤/搜索