当前位置: 首页 > article >正文

C++ 内部类

 个人主页:Jason_from_China-CSDN博客

所属栏目:C++系统性学习_Jason_from_China的博客-CSDN博客

所属栏目:C++知识点的补充_Jason_from_China的博客-CSDN博客

概念概述

  • 如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,跟定义在全局相比,他只是受外部类类域限制和访问限定符限制,所以外部类定义的对象中不包含内部类。
  • 内部类默认是外部类的友元类。
  • 内部类本质也是一种封装,当 A 类跟 B 类紧密关联,A 类实现出来主要就是给 B 类使用,那么可以考虑把 A 类设计为 B 的内部类,如果放到 private/protected 位置,那么 A 类就是 B 类的专属内部类,其他地方都用不了。

内部类的使用1

正常代码

class A
{
public:
	A();
	~A();

private:

};

class B
{
public:
	B();
	~B();

private:

};

内部类的代码

#include<iostream>
using namespace std;
class A
{
public:
	A(int a1 = 1, int a2 = 1) 
		:_a1(a1)
		,_a2(a2)
	{};

	class B
	{
	public:
		//错误写法,内部类和外部类是相对独立的,是不能直接访问的
		//B(int b1 = _a1, int b2 = _a2)

		//B()
		//{}


		直接访问类(这里没有默认构造)
		//B(const A a)
		//	:_b1(a._a1)
		//	,_b2(a._a2)
		//{}

		//默认构造写法
		B(int b1 = 2, int b2 = 2)
			:_b1(b1)
			,_b2(b2)
		{}
		void _print()
		{
			cout << "内部类默认是外部类的友元函数" << endl;
		}
	private:
		int _b1;
		int _b2;
	};
private:
	int _a1 = 1;
	int _a2 = 1;
};



int main()
{
	A a;
	A::B b;

	return 0;
}

注意事项:

  • 内部类和外部类是相对独立的,外部类构造时,不能直接将构造的数值传递给内部类。外部类先构造,但在外部类构造函数执行时,内部类的对象可能还未创建,内部类的作用域在外部类内部,外部类构造函数不能直接访问还未创建的内部类对象的成员。
    下图我们就可以看出来,我们直接从外部类构造的数值去初始化内部类是不能成功的,需要默认构造函数

但是我们加上默认构造是可以的,说明,内部类和外部类是相对独立的

  • 内部类默认是外部类的友元函数(内部类的调用受到访问限定符的限制)

这里我们发现A类,突破类域就可以访问B,但是B不能说突破类域访问A

  • 如果你需要把外部类的构造给内部类使用,那么我们可以采取get成员函数的方式,或者静态成员变量的方式来进行使用

#include<iostream>
using namespace std;
class A
{
public:
	A(int a1 = 1, int a2 = 1) 
		:_a1(a1)
		,_a2(a2)
	{};
	int geta1()
	{
		return _a1;
	}
	class B
	{
	public:
		//直接访问类(这里没有默认构造)(可以接收参数)
		B(const A a)
			:_b1(a._a1)
			,_b2(a._a2)
		{}

		//默认构造写法
		B(int b1 = 2, int b2 = 2)
			:_b1(b1)
			,_b2(_b2)
		{}
	private:
		int _b1;
		int _b2;
	};
private:
	int _a1 = 1;
	int _a2 = 1;
};


int main()
{
	A a;
	int ret1 = a.geta1();
	A::B b = { ret1 };

	return 0;
}

内部类的使用2: 

没有学习之前:

这里我使用vs编译器,vs编译器不支持可边长数组,所以代码有点不一样

#include<iostream>
using namespace std;
//求1+2......+n//不能使用乘除
class sum
{
public:
	sum()
	{
		_ret += _i;
		++_i;
	}
	//获取ret最终的结果
	static int _GetRet()
	{
		return _ret;
	}
private:
	static int _i;
	static int _ret;
};
int sum::_i = 1;
int sum::_ret = 0;


class solution
{
public:
	int _solution(int n)
	{
		for (int i = 0; i < n; i++)
		{
			//创建n次构造函数,n次构造函数++会依次递加
			sum s;
		}
		//创建n次数之后,我们计算出来数值,此时我们可以选择数值来进行接收
		int ret = sum::_GetRet();
		//打印数值
		cout << ret << endl;

		//返回数值
		return sum::_GetRet();
	}
};

int main()
{
	solution s;
	int ret = s._solution(100);//这里接收进行验证,发现是正确的
	cout << ret << endl;//打印出来
	return 0;
}

sum

  1. 成员变量:

    • static int _i:静态成员变量,用于记录当前要累加的数字。初始化为 1。
    • static int _ret:静态成员变量,用于存储累加的结果。初始化为 0。
  2. 构造函数:

    • 每次创建 sum 类的对象时,构造函数被调用。在构造函数中,将当前的 _i 值累加到 _ret 中,然后将 _i 的值自增。这样,每次创建对象就相当于进行一次累加操作。
  3. 静态成员函数 _GetRet()

    • 用于获取 _ret 的值,即累加的结果。

solution

  1. 成员函数 _solution(int n)
    • 这个函数接受一个整数 n,目的是计算从 1 加到 n 的和。
    • 通过一个循环创建 n 次 sum 类的对象。每次创建对象时,sum 类的构造函数会自动进行累加操作。
    • 最后,通过 sum::_GetRet() 获取累加的结果,并将其赋值给 ret,然后打印和返回这个结果。

学习之后:

这里采取的是vs编译器,vs编译器是不支持可变长数组的,所以代码有点出入

#include<iostream>
using namespace std;
class sol
{
	//内部类
	class Sum
	{
	public:
		Sum()
		{
			_ret += _i;
			++_i;
		}

		static int _i;
		static int _ret;
	};

public:
	static int _sol(int n)
	{
		for (size_t i = 0; i < n; i++)
		{
			Sum s;
		}
        //这里不需要成员函数了,直接可以访问私有变量
		return Sum::_ret;
	}
};

//这里需要注意一下,因为我们需要突破类域
int sol::Sum::_i = 1;
int sol::Sum::_ret = 0;

int main()
{
	sol s;
	int ret = s._sol(100);
	cout << ret << endl;
	return 0;
}

http://www.kler.cn/news/340775.html

相关文章:

  • Python测试库介绍及示例
  • xss 跨站脚本攻击
  • React中useState、useReducer与useRef
  • linux中软连接和硬链接的区别
  • 基于SpringBoot+Vue的蛋糕甜品商城系统
  • 10.9 C高级-shell脚本4
  • MySql 之 Binglog 复制
  • OpenCV图像处理学习前简介
  • 【Linux 从基础到进阶】数据湖解决方案在 Linux 上的实现
  • 高性能架构——计算高性能
  • aws(学习笔记第二课) AWS SDK(node js)
  • ESP32-C3实现GPIO输出高低电平
  • C++学习笔记(50)
  • [面试] java开发面经-1
  • 张雪峰谈人工智能技术应用专业的就业前景!
  • 多路复用——poll
  • 了解Java的基础
  • 单细胞转录组 —— STARsolo 原始数据处理
  • L0-Linux-关卡材料提交
  • 初始Linux(二)基础命令