第五章及其嵌套类
2013-10-26 15:10
246 查看
1.需要控制对结构成员的访问有两个理由:一是让客户程序员远离一些他们不需要使用的工具,这些工
具对数据类型内部的出来说是必需的。二是允许库的设计者改变类的内部实现,而不必担心会对客户程
序员产生影响
2.
struct X;
struct Y {
void f(X*);声明
};
struct X { // Definition
private:
int i;
public:
void initialize();
friend void g(X*, int); // Global friend//声明的同时作为友元
friend void Y::f(X*); // Struct member friend//仅仅说明作为友元
friend struct Z; // Entire struct is a friend//不完整的类型说明只为作为友元
friend void h();
};
void Y::f(X* x) { //定义
x->i = 47;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
嵌套类的名字在其外围类的作用域中可见,但在其他类作用域或定义外围类的作用域中不可见。嵌套类
的名字将不会与另一作用域中声明的名字冲突。
嵌套类定义了其外围类中的一个类型成员。像任何其他成员一样,外围类决定对这个类型的访问
在外围类的 public 部分定义的嵌套类定义了可在任何地方使用的类型
在外围类的 protected 部分定义的嵌套类定义了只能由外围类、友元或派生类访问的类型,
在外围类的 private 部分定义的嵌套类定义了只能被外围类或其友元访问的类型
使用嵌套类的原因:
第一 是命名空间的问题,在类里面定义的类或者结构不怕重名,并且强调了两个类(外围类和嵌套类)之
间的主从关系,比如说模板类每个类都有个iterator嵌套类,重名也不要紧
第二 是可以把类定义成private或者protected,提供访问保护机制。
第三 之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用
于外围类的实现,且同时可以对用户隐藏该底层实现。而只在外围类中前向声明这个嵌套类即可
虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类
,同样,外围类的成员也不属于该嵌套类。
嵌套类的出现只是告诉外围类有一个这样的类型成员供外围类使用。
并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员有特权(新的标准允许了)
它们都遵循普通类所具有的标号访问控制。
另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,即使这些是private的
声明外围类的对象时,不会牵涉到其嵌套类;反之亦然。
模版姓的嵌套类静态成员定义:
template<class type>
int lei<type>::leizi::static_num=100;
具对数据类型内部的出来说是必需的。二是允许库的设计者改变类的内部实现,而不必担心会对客户程
序员产生影响
2.
struct X;
struct Y {
void f(X*);声明
};
struct X { // Definition
private:
int i;
public:
void initialize();
friend void g(X*, int); // Global friend//声明的同时作为友元
friend void Y::f(X*); // Struct member friend//仅仅说明作为友元
friend struct Z; // Entire struct is a friend//不完整的类型说明只为作为友元
friend void h();
};
void Y::f(X* x) { //定义
x->i = 47;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
嵌套类的名字在其外围类的作用域中可见,但在其他类作用域或定义外围类的作用域中不可见。嵌套类
的名字将不会与另一作用域中声明的名字冲突。
嵌套类定义了其外围类中的一个类型成员。像任何其他成员一样,外围类决定对这个类型的访问
在外围类的 public 部分定义的嵌套类定义了可在任何地方使用的类型
在外围类的 protected 部分定义的嵌套类定义了只能由外围类、友元或派生类访问的类型,
在外围类的 private 部分定义的嵌套类定义了只能被外围类或其友元访问的类型
使用嵌套类的原因:
第一 是命名空间的问题,在类里面定义的类或者结构不怕重名,并且强调了两个类(外围类和嵌套类)之
间的主从关系,比如说模板类每个类都有个iterator嵌套类,重名也不要紧
第二 是可以把类定义成private或者protected,提供访问保护机制。
第三 之所以引入这样一个嵌套类,往往是因为外围类需要使用嵌套类对象作为底层实现,并且该嵌套类只用
于外围类的实现,且同时可以对用户隐藏该底层实现。而只在外围类中前向声明这个嵌套类即可
虽然嵌套类在外围类内部定义,但它是一个独立的类,基本上与外围类不相关。它的成员不属于外围类
,同样,外围类的成员也不属于该嵌套类。
嵌套类的出现只是告诉外围类有一个这样的类型成员供外围类使用。
并且,外围类对嵌套类成员的访问没有任何特权,嵌套类对外围类成员有特权(新的标准允许了)
它们都遵循普通类所具有的标号访问控制。
另外,嵌套类可以直接引用外围类的静态成员、类型名和枚举成员,即使这些是private的
声明外围类的对象时,不会牵涉到其嵌套类;反之亦然。
模版姓的嵌套类静态成员定义:
template<class type>
int lei<type>::leizi::static_num=100;
/////////////////////////////////////////////////////头文件 #ifndef NESTCLASS_H_ #define NESTCLASS_H_ class A { public: A(); ~A(); void operate(); private: class B; B* m_b; }; #endif /////////////////////////////////////////////////////实现 #include "nestclass.h" #include <iostream> 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 ///将会引发一个编译错误 class Obj_A { public: Obj_A() { a = 10; } class Obj_B { friend class Obj_A; //外围类要想访问嵌套类private成员必须声明为friend public: Obj_B() { a = 20; } void f(Obj_A a) { a.a = 1; //嵌套类可以随意访问外围类的private成员///////////C++新标准 } private: int a; }; void f(Obj_B b) { b.a = 1; } private: int a; };
相关文章推荐
- Matlab基本函数-ceil函数
- 【多线程】——join()方法实现并行计算
- php中实现HmacMd5算法的源代码
- PHP上传图片在不同浏览器和浏览器模式中的问题及解决 image/jpeg 和 image/pjpeg
- 【面向对象】——编译时看父类,运行时看子类
- django1.5.5使用mysql
- Eqs hash表存储,注意hash要用char类型
- 关于java正则表达式贪婪模式和勉强模式的研究
- Lucene 需要索引的文本文件太大,怎么解决?
- LDD3源码学习日记<四>
- LeetCode:Candy
- hdu 2897 邂逅明下 博弈
- Django class-based view
- Java中常用的时间的计算
- 【重点】让类对象具有比较性,装入TreeSet【用来排序】
- 学习笔记(一)之示例程序:计算每年的最高温度MaxTemperature
- poj——2063——Investment(dp)
- can't connect to X11 server,Cannot initialise screen
- 【CQOI 2006】 简单题
- PBSQLScipt 数据库管理工具V3.0