C++类基础8——嵌套类和局部类

本文解析了嵌套类的实例、访问规则,以及局部类的定义和限制,展示了C++中类结构的复杂性与访问控制机制。
摘要由CSDN通过智能技术生成

嵌套类

一个类可以定义在另一个类的内部,前者称为嵌套类或嵌套类型。

下面是一个使用C++嵌套类的示例:

#include <iostream>

class OuterClass {
public:
    class InnerClass {
    public:
        void printMessage() {
            std::cout << "Hello from InnerClass!" << std::endl;
        }
    };

    void callInnerClass() {
        InnerClass inner;
        inner.printMessage();
    }
};

int main() {
    OuterClass outer;
    outer.callInnerClass();

    return 0;
}

在上面的代码中,OuterClass有一个嵌套类InnerClass。在OuterClasscallInnerClass()函数中,我们创建了InnerClass的一个对象,并调用了它的printMessage()函数。最终的输出结果将会是"Hello from InnerClass!"。

嵌套类的性质

嵌套类常用于定义作为实现部分的类

  1. 嵌套类是一个独立的类,与外层类基本没什么关系。
  2. 特别是,外层类的对象和嵌套类的对象是相互独立的。
  3. 在嵌套类的对象中不包含任何外层类定义的成员;
  4. 类似的,在外层类的对象中也不包含任何嵌套类定义的成员。

嵌套类的名字在外层类作用域中是可见的,在外层类作用域之外不可见。

class A
{
	class B
	{
	
	};
	B a;//正确
};

B b;//错误

和其他嵌套类的名字不会和别的作用域中的同一个名字冲突。

class B
{
};
class A
{
	class B//不冲突
	{
	
	};

};

嵌套类中成员的种类与非嵌套类是一样的。

class A
{
	class B
	{
	
	};
	B a;
	int b;//a,b都是成员
};

和其他类类似,嵌套类也使用访问限定符的名字一样,来控制外界对其成员的访问权限。

class A
{

	class B
	{
	public:
		int b;
		
	};

};

外层类对嵌套类的成员没有特殊的访问权限,同样,嵌套类对外层类的成员也没有特殊的访问权限。

class A
{
public:
	int a;
	class B
	{
      public:
		int b;
		void C()
		{
			cout << a << endl;//错误,嵌套类对外部类成员没有特殊访问权限
		}
	};
	void D()
	{
		cout << b << endl;//错误,外部类对嵌套类成员没有特殊访问权限
	}
};

嵌套类在其外层类中定义了一个类型成员。和其他成员类似,该类型的访问权限由外层类决定。

  1. 位于外层类public部分的嵌套类实际上定义了一种可以随处访问的类型;
  2. 位于外层类protected部分的嵌套类定义的类型只能被外层类及其友元和派生类访问:
  3. 位于外层类private部分的嵌套类定义的类型只能被外层类的成员和友元访问。
class OuterClass {
public:
    class NestedClass {
    public:
        void doSomething() {
            // 嵌套类的成员实现
        }
    };

    NestedClass nestedObj; // 嵌套类对象

    void useNestedClassMember() {
        nestedObj.doSomething(); // 调用嵌套类的成员
    }
};

int main() {
    OuterClass outerObj;
    outerObj.useNestedClassMember(); // 通过外部类对象调用嵌套类的成员
    return 0;
}

声明一个嵌套类

我们举个例子

class A {
public: 
class B; //嵌套类稍后定义
//...
};

我们只需对原来的A类做一处改动,即将B声明成嵌套类。

因为B是一个类型成员,所以我们必须对它先声明后使用.

在外层类之外定义一个嵌套类 

我们在A内声明了B,但是没有给出它的定义。

和成员函数一样,嵌套类必须声明在类的内部,但是可以定义在类的内部或者外部。

当我们在外层类之外定义一个嵌套类时,必须以外层类的名字限定嵌套类的名字;

class A::B
{
public:
int a;
}

在嵌套类在其外层类之外完成真正的定义之前,它都是一个不完全类型

定义嵌套类的成员

在这个版本的A类中,我们并没有在类的内部定义其构造函数。

要想为其定义构造函数,必须指明B是嵌套在A的作用域之内的。具体做法是使用外层类的名字限定联套类的名字:

A::B::B(int a_):a(a_){}

该构造函数除了把实参值赋给对应的数据成员之外,没有做其他工作。

访问嵌套类的成员

我们访问嵌套类成员只能通过创建嵌套类对象才能访问!!!

class A
{
public:
	int a;
	class B
	{
	public:
		void C()
		{
			cout << "使用成功" << endl;
		}
	}; 
	B b;
	void A1()
	{
		b.C();//通过嵌套类对象使用其中的数据成员
	}
};

我们不能直接在外部类里直接访问嵌套类成员

嵌套类的静态成员定义

如果B声明了一个静态成员,则该成员的定义将位于A的作用域之外。

例如,假设B有一个静态成员,则该成员的定义将形如:

int A::B::static_mem= 1024;

嵌套类作用域中的名字查找

名字查找的一般规则在嵌套类中同样适用。

当然,因为嵌套类本身是一个嵌套作用域,所以还必须查找嵌套类的外层作用域。

class A
{
public:
	int a;
	class B
	{
	}; 
	B N()//我们可以随意使用B这个名字
	{
		;
	}
};

嵌套类和外层类是相互独立的

尽管嵌套类定义在其外层类的作用域中,但是读者必须谨记外层类的对象和嵌套类的对象没有任何关系。

嵌套类的对象只包含嵌套类定义的成员;

同样,外层类的对象只包含外层类定义的成员,在外层类对象中不会有任何嵌套类的成员。

有的人可能会写出下面这样子的代码

这个程序企图通过一个A类对象来使用B类的成员,但是这是错误的,A类和B类的数据成员没有任何特殊访问权限,它们是相互独立的,要想访问B类的数据成员,只能通过一个B类对象来实现

局部类

类可以定义在某个函数的内部,我们称这样的类为局部类。

局部类定义的类型只在定义它的作用域内可见。

和嵌套类不同,局部类的成员受到严格限制。

局部类的所有成员(包括函数在内)都必须完整定义在类的内部。因此,局部类的作用与嵌套类相比相差很远

在实际编程的过程中,因为局部类的成员必须完整定义在类的内部,所以成员函数的复杂性不可能太高。局部类的成员函数一般只有几行代码,否则我们就很难读懂它了。

类似的,在局部类中也不允许声明静态数据成员,因为我们没法定义这样的成员。

局部类不能使用函数作用域中的变量

局部类对其外层作用域中名字的访问权限受到很多限制,局部类只能访问外层作用域定义的类型名、静态变量以及枚举成员。
如果局部类定义在某个函数内部,则该函数的普通局部变量不能被该局部类使用:

int a, val;
void foo(int val)
{
	static int si;
	enum Loc { a = 1024, b };
	// Bar是foo的局部类
	struct Bar {
		Loc locVal; // 正确:使用一个局部类型名
		int barVal;
		void fooBar(Loc l = a) // 正确:默认实参是Loc::a
		{
			barVal = val; //错误:val是foo的局部变量
			barVal = ::val; // 正确:使用一个全局对象
			barVal = si; // 正确:使用一个静态局部对象
			locVal = b; // 正确:使用一个枚举成员
		}
	};
}


常规的访问保护规则对局部类同样适用

外层函数对局部类的私有成员没有任何访问特权。

当然,局部类可以将外层函数声明为友元;或者更常见的情况是局部类将其成员声明成公有的。

在程序中有权访问局部类的代码非常有限。局部类已经封装在函数作用域中,通过信息隐藏进一步封装就显得没什么必要了。

局部类中的名字查找

局部类内部的名字查找次序与其他类相似。

在声明类的成员时,必须先确保用到的名字位于作用域中,然后再使用该名字。

定义成员时用到的名字可以出现在类的任意位置。

如果某个名字不是局部类的成员,则继续在外层函数作用域中查找;如果还没有找到,则 在外层函数所在的作用域中查找。

嵌套的局部类

可以在局部类的内部再嵌套一个类。

此时,嵌套类的定义可以出现在局部类之外。

不嵌套类必须定义在与局部类相同的作用域中。

void foo()
{
	class Bar {
	public:
		//...
		class Nested;// 声明Nested类
	};
	//定义Nested类

	class Bar::Nested
	{
		//...
	};
};


和往常一样,当我们在类的外部定义成员时,必须指明该成员所属的作用域。因此在上面的例子中,Bar::Nested的意思是Nested是定义在Bar的作用域内的一个类。

局部类内的嵌套类也是一个局部类,必须遵循局部类的各种规定。嵌套类的所有成员都必须定义在嵌套类内部。
 

 

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值