嵌套类和局部类在工作中极少使用,且均可在设计上替代,这里仅做简要介绍。
1)局部类
局部类就是将类定义在函数中。形如:
int val = 100;
void foo(int val)
{
struct Bar
{
};
class Bar::InsideClass//定义InsideClass类
{
};
}
2)嵌套类
嵌套类就是将一个类定义在另一个类中。形如:
class Interface
{
public:
virtual void Fun() = 0;
};
template <class T, class P>
Interface* Person(const T& obj, const P& arg)
{
int x;
class Local : public Interface
{
public:
Local(const T& obj, const P& arg)
: obj(obj), arg(arg) {}
virtual void Fun()
{
}
private:
T a;
P b;
};
return new Local(obj, arg);
}
嵌套类必须声明在类的内部,但是可以定义在类的内部或者外部。在外层类之外定义一个嵌套类时,必须以外层类的名字限定嵌套类的名字。
嵌套类的名字只在外围类可见。
类的私有成员只有类的成员和友元可以访问,因此外围类不可以访问嵌套类的私有成员。嵌套类可以访问外围类的成员(通过对象、指针或者引用)。
一个好的嵌套类设计:嵌套类应该设成私有。嵌套类的成员和方法可以设为 public 。
嵌套类可以直接访问外围类的静态成员、类型名( typedef )、枚举值。
(内部类与外部类)
1.1 作用域
嵌套类的声明位置决定了嵌套类的作用域,即它决定了程序的那部分可以创建嵌套类的对象。
如果嵌套类声明在一个类的私有部分,则只有嵌套类的外部类可以知道它。上面的类就是这种情况。
如果嵌套类声明在一个类的保护部分,对于后者是可见的,对于外界是不可见的。派生类知道该嵌套类,并且可以直接创建这种类型的对象。
如果嵌套类声明在一个类的公有部分,则允许后者,后者的派生类以及外部世界使用。然后在外部使用时,必须加上外部类的外部类作用域限制符,如: 使用NestedClass 时,应该这样定义 OutClass::NestedClass nestedInstance.
嵌套结构和枚举的作用域于此相同。许多程序员使用公有的枚举提供客户使用的类常量。
下面表格总结了,嵌套类、结构、枚举的作用域特征。
1.2 访问权限
在外部类中声明嵌套类并没有赋予外部类任何对嵌套类的访问权限,也没有赋予任何嵌套类对于外部类的访问权限。与一般类的访问控制相同(私有,公有,保护)。
局部类
类可以定义在某个函数的内部,这样的类被称为局部类,局部类定义的类型只在定义它的作用域内可见。
局部类不能使用函数作用域中的变量。
局部类已经封装在函数作用域中,通过信息隐藏进一步封装就显得没什么必要了。
可以在局部类的内部再嵌套一个类,此时,嵌套类的定义可以出现在局部类之外且与局部类相同的作用域中。
(c++不能在函数中定义函数。c++在类中定义的函数也就是成员函数。)这个类以及由它创建的对象,都局限在该函数作用域中;必须在类内实现所有的成员函数,不能拿到类外。因为函数是不可以嵌套定义的;若类内含有静态数据成员,必须在该函数外初始化;类内不可含有静态函数成员;类中不可使用包裹它的函数所定义的除静态外的局部变量。
c++内部类与java内部类的区别就是:
c++的内部类对象没有外部类对象的指针,不能访问外部类对象的非静态成员;java的非静态内部类对象有外部类对象的指针,能访问外部类对象的非静态成员。
1 局部类Demo 示例
int a;
void fun()
{
static int s;
class A
{
public:
void init(int i) { s = i; }
};
A m;
m.init(10);
}
2 局部类的另一个用途是用来实现类型转化
class Interface
{
public:
virtual void Fun() = 0;
};
template <class T, class P>
Interface* MakeAdapter(const T& obj, const P& arg)
{
int x;
class Local : public Interface
{
public:
Local(const T& obj, const P& arg)
: obj(obj), arg(arg) {}
virtual void Fun()
{
x = 100;
obj.Call(arg);
}
private:
T obj;
P arg;
};
return new Local(obj, arg);
}
.内嵌类
是在类体内定义的又一个类。外面的类叫外围类。这个类以及由它创建的对象,都局限在外层类作用域中;
外界能否使用内层类,全在于访问权限;若能使用,定要以外围类::内层类格式来用;
是类组合演化的又一种类间关系,即组合或聚集成员不是产生于其它类,而是产生于内层类;内层类的成员函数,可以在类内实现,也可以在外层类之外实现;
内层类的成员函数对外围类的成员没有访问权,反之亦然
定义嵌套类的目的在于隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。这样可以提高类的抽象能力,并且强调了两个类(外围类和嵌套类)之间的主从关系。
1 下面是一个嵌套类的例子
class A
{
public:
class B
{
public:
…
private:
…
};
void f();
private:
int a;
}
其中,类B是一个嵌套类,类A是外围类,类B定义在类A的类体内。
2 对嵌套类的若干说明:
1、从作用域的角度看,嵌套类被隐藏在外围类之中,该类名只能在外围类中使用。如果在外围类的作用域内使用该类名时,需要加名字限定。
2、从访问权限的角度来看,嵌套类名与它的外围类的对象成员名具有相同的访问权限规则。不能访问嵌套类的对象中的私有成员函数,也不能对外围类的私有部分中的嵌套类建立对象。
3、嵌套类中的成员函数可以在它的类体外定义。
4、嵌套类中说明的成员不是外围类中对象的成员,反之亦然。嵌套类的成员函数对外围类的成员没有访问权,反之亦然。国此,在分析嵌套类与外围类的成员访问关系时,往往把嵌套类看作非嵌套类来处理。
上述的嵌套类可写成如下格式:
class A
{
public:
void f();
private:
int a;
};
class B
{
public:
…
private:
…
};
由引可见,嵌套类仅仅是语法上的嵌入。
5、在嵌套类中说明的友元对外围类的成员没有访问权。
6、如果嵌套类比较复杂,可以只在外围类中对嵌套类进行说明,关于嵌套的详细的内容可在外围类体外的文件域中进行定义。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。