C++中局部类的使用

类可以定义在某个函数的内部,我们称这样的类为局部类(local class)。局部类定义的类型只在定义它的作用域内可见。和嵌套类不同,局部类的成员受到严格控制。局部类的所有成员(包括函数在内)都必须完整定义在类的内部。因此,局部类的作用与嵌套类相比相差很远。局部类只在函数内部有效,无法在函数外部调用。

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

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

常规的访问保护规则对局部类同样适用:外层函数对局部类的私有成员没有任何访问特权。当然,局部类可以将外层函数声明为友元;或者更常见的情况是局部类将其成员声明成公有的。在程序中有权访问局部类的代码非常有限。局部类已经封装在函数作用域中,通过信息隐藏进一步封装就显得没什么必要了。

局部类中的名字查找:局部类内部的名字查找次序与其它类相似。在声明类的成员时,必须先确保用到的名字位于作用域中,然后再使用该名字。定义成员时用到的名字可以出现在类的任意位置。如果某个名字不是局部类的成员,则继续在外层函数作用域中查找;如果还没有找到,则在外层函数所在的作用域中查找。

嵌套的局部类:可以在局部类的内部再嵌套一个类。此时,嵌套类的定义可以出现在局部类之外。不过,嵌套类必须定义在与局部类相同的作用域中。局部类内的嵌套类也是一个局部类,必须遵循局部类的各种规定。嵌套类的所有成员都必须定义在嵌套类内部。

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "local_class.hpp"
#include <iostream>
#include <vector>
#include <algorithm>

namespace local_class_ {
// reference: C++ Primer(Fifth Edition) 19.7
int a{ 0 }, val{ 0 };

void foo(int val)
{
	static int si;
	enum Loc {a = 1024, b};
	// Bar is local to foo
	struct Bar {
		Loc locVal; // ok: uses a local type name
		int barVal;

		void fooBar(Loc l = a) // ok: default argument si Loc::a
		{
			//barVal = val; // error: val is local to foo
			barVal = ::local_class_::val; // ok: uses a global object
			barVal = si; // ok: uses a static local object
			locVal = b; // ok: use an enumerator
		}
	};
}

int test_local_class_1()
{
	return 0;
}

////////////////////////////////////////////////
// reference: http://www.geeksforgeeks.org/local-class-in-c/
void fun()
{
	class Test { // local to fun
	public:
		// Fine as the method is defined inside the local class
		void method() {
			std::cout << "Local Class method() called" << std::endl;
		}
	};

	Test t;
	t.method();
}
int test_local_class_2()
{
	fun();
	return 0;
}

/////////////////////////////////////////////////////
// reference: http://www.geeksforgeeks.org/local-class-in-c/
void fun2()
{
	class Test { // local to fun
	public:
		static void method()
		{
			std::cout << "Local Class method() called"<<std::endl;
		}
	};

	Test::method();
}
int test_local_class_3()
{
	fun2();
	return 0;
}

/////////////////////////////////////////////////////
// http://www.geeksforgeeks.org/local-class-in-c/
void fun3()
{
	static int x = -3;
	enum { i = 1, j = 2 };

	// Local class
	class Test {
	public:
		void method() {
			std::cout << "x = " << x << std::endl;   // fine as x is static
			std::cout << "i = " << i << std::endl;   // fine as i is enum
		}
	};

	Test t;
	t.method();
}

int test_local_class_4()
{
	fun3();
	return 0;
}

///////////////////////////////////////////////////////////
// http://www.geeksforgeeks.org/local-class-in-c/
int x = 11;

void fun4()
{

	// First Local class
	class Test1 {
	public:
		Test1() { std::cout << "Test1::Test1()" << std::endl; }
	};

	// Second Local class
	class Test2 {
		// Fine: A local class can use other local classes of same function
		Test1 t1;
	public:
		void method() {
			// Fine: Local class member methods can access global variables.
			std::cout << "x = " << x << std::endl;
		}
	};

	Test2 t;
	t.method();
}

int test_local_class_5()
{
	fun4();
	return 0;
}

/////////////////////////////////////////////////////////
// reference: https://stackoverflow.com/questions/3235172/local-classes-in-c
int pqr()
{
	class abc {
		int x;
	public:
		abc() : x(4) { }
		friend int pqr();
	};
	return abc().x;
}

int test_local_class_6()
{
	std::cout << "Return " << pqr() << std::endl;
	return 0;
}

//////////////////////////////////////////////////////////
// reference: https://www.hscripts.com/tutorials/cpp/local-classes.php
int y;
void g()
{
	class local {
	public:
		void put(int n) { ::local_class_::y = n; }
		int get() { return ::local_class_::y; }
	} ab;

	ab.put(20);
	std::cout << "The value assigned to y is::" << ab.get() << std::endl;
}

int test_local_class_7()
{
	g();
	return 0;
}

//////////////////////////////////////////////////////
// reference: http://en.cppreference.com/w/cpp/language/class
int test_local_class_8()
{
	struct Local {
		bool operator()(int n, int m) {
			return n > m;
		}
	};

	std::vector<int> v{ 1, 2, 3 };
	std::sort(v.begin(), v.end(), Local()); // since C++11
	for (int n : v) std::cout << n << ' ';
	std::cout << std::endl;

	return 0;
}

} // namespace local_class_

GitHub:  https://github.com/fengbingchun/Messy_Test
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值