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
相关文章
相关标签/搜索