摩根斯坦利2013年机试题(一) 嵌套类

本文深入探讨了C++中嵌套类的概念与应用,包括嵌套类的定义、使用方法、与外围类的关系以及如何在模板类中使用嵌套类等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在一个类内部定义一个类,这个类被称之为嵌套类,或嵌套类型。之所以引用嵌套类,往往是因为外围类需要嵌套类对象作为底层实现,并且嵌套类只用于该外围类的实现,同时可以对用户隐藏该底层实现。

嵌套类是一个单独的类,它和外围类是相互独立的,它不具备外围类所定义的成员,同样外围类也不具备嵌套类所定义的成员

同样,外围类对嵌套类没有特别的访问权限,嵌套类对外围了也没有特别的访问权限。friend友元关系也不可以传递

class Base
{
public:
	Base(){cout<<"Base\n"<<endl;}
private:
	friend class Friend;
	int b;
public:
	class Nest{
	public:
		Nest(){cout<<"Nest\n"<<endl;
		}
	private:
		int a;
	};
};
class Friend
{
public:
	void friendtest();
};
void Friend::friendtest()
{
	Base base;
	base.b=11;
	Base::Nest nest;
	nest.a=10;/*无法访问private成员*/
}

对于嵌套类的使用就当成一个类型定义,使用该类型定义一个对象即Base::Nest 与在类内用typedef定义的类型一样.

嵌套类定义时内部可以直接引用外围类的static变量,类型(typedef定义的),枚举类型即使是private

静态成员变量无论是在嵌套类前面声明或者后面声明都可以引用

类型和enum类型必须在嵌套类定义才可以使用

class Base
{
public:
	Base(){cout<<"Base\n"<<endl;}
private:
	enum Color{RED,BLACK};
	typedef char* pchar;
public:
	class Nest{
	public:
		Nest():a(b){cout<<"Nest\n"<<endl;
		cout<<"Nest::a="<<a<<endl;
		co=RED;
		}
		int a;
		Color co;
		pchar pp;
	};
	Nest P; /*定义了嵌套类对象 若未定义其不会构造嵌套类*/
private:
	static int b;
};
int Base::b=1;
void main()
{
	Base B;
}

输出结果为

Nest

Nest::a=1

Base

为什么是先构造Nest呢?涉及到构造过程

EffectiveC++条款12:尽量使用初始化而不要在构造函数里赋值

指出:对象的创建分两步:

1. 数据成员初始化。

2. 执行被调用构造函数体内的动作。

构造函数的初始化列表属于第一步,若并未给予赋值则调用对数据成员默认初始化,类数据成员会调用默认构造函数。上述代码中定义了Nest类型的数据成员P,因此会调用Nest默认构造函数。Base的函数体是最后执行的,因此Nest在Base之前输出。

 

在类外部定义嵌套类,与一般的类定义没什么区别,加了一个作用域限定符

template <typename T>
class Base
{
public:
	Base(){cout<<"Base\n"<<endl;}
private:
	T a;
	class Nest; /*前向声明 不完全类型*/
	Nest *p;
};

template<typename T>
class Base<T>::Nest{
	public:
		Nest(const T&t):b(t){cout<<"Nest\n"<<endl;}
	private:
		T b;
		static int c;
	};
template<typename T> int Base<T>::Nest::c=10;

模版

外围类是一个模板,则嵌套类也隐含是模板,其模板形参与外围类相同

实例化外围模板时并不会自动实例化类模板的嵌套类。像任何成员一样,只有当在需要完整类类型的情况下使用嵌套类本身的时候,才会实例化嵌套类

template <typename T>
class Base
{
public:
	Base(){cout<<"Base\n"<<endl;}
private:
	T a;
	class Nest{
	public:
		Nest(const T&t):b(t){cout<<"Nest\n"<<endl;}
	private:
		T b;
		static int c;

	};
	Nest *p;
};
template<typename T> int Base<T>::Nest::c=10;

上述代码中若将Base实例化Base<int> B;并不会实例化嵌套类Nest,因为Base里的对象Nest是一个指针,只有当对其解引用是才会实例化Nest<int>

 

继承

三种访问权限

    public:可以被任意实体访问

    protected:只允许子类及本类的成员函数访问

private:只允许本类的成员函数访问

继承的访问权限

1、public继承不改变基类成员的访问权限

2、private继承使得基类所有成员在子类中的访问权限变为private

3、 protected继承将基类中public成员变为子类的protected成员,其它成员的访问权限不变。

4、基类中的private成员不受继承方式的影响,子类永远无权访问。

由于嵌套类跟外围类是个相对独立的类,基类无法访问嵌套类的protected的成员,自然基类的派生类也无法访问,但嵌套类可以被继承

#include <iostream>
using namespace std;
template <typename T>
class Base
{
public:
	Base(){cout<<"Base\n"<<endl;}
protected:
	T a;
	class Nest;/*前向声明 不完全类型*/
	Nest *p;
};

template<typename T>
class Base<T>::Nest{
	public:
		Nest(const T&t):b(t){cout<<"Nest\n"<<endl;}
	protected:	
void nestdisplay(){cout<<"nestdisplay b="<<b<<endl;}
	private:
		T b;
		static int c;

	};
template<typename T> int Base<T>::Nest::c=10;
template <typename T>
class Derived:public Base<T>
{
public:
	Derived(){cout<<"derived\n"<<endl;}
	void derivedtest(T& a);
private:
	int d;
};
template <typename T>
void Derived<T>::derivedtest( T& a)
{
	p=new Nest(a);
	p->nestdisplay();/*若将其nestdisplay声明为protected 则Derived继承类无法访问nestdisplay成员函数*/

	delete p;
}
void main()
{
Derived<int> D;
int a=3;
D.derivedtest(a);
}

局部类与嵌套类的区别,一般很少用局部类

见http://www.cnblogs.com/charley_yang/archive/2011/04/05/2005897.html


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值