返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++类与对象深入之静态成员与友元及内部类详解
  • 398
分享到

C++类与对象深入之静态成员与友元及内部类详解

2024-04-02 19:04:59 398人浏览 独家记忆
摘要

目录一:静态成员1.1:静态成员分类1.2:静态成员变量1.3:静态成员函数1.4:总结特性1.5:试题示例1.6:c++11成员初始化新玩法二:友元2.1:全局函数做友元2.2:类

一:静态成员

静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员。C++里面尽量用静态成员变量代替全局变量。

1.1:静态成员分类

1️静态成员变量:

  • 所有对象共享同一份数据
  • 在编译阶段分配内存
  • 类内声明,类外初始化

静态成员函数

  • 所有对象共享同一个函数
  • 静态成员函数只能访问静态成员变量

1.2:静态成员变量

class Person
{
public:
	static int m_A; //静态成员变量
private:
	static int m_B; //静态成员变量也是有访问权限的
};
int Person::m_A = 10;
int Person::m_B = 10;
void test01()
{
	//静态成员变量两种访问方式
	//1、通过对象
	Person p1;
	p1.m_A = 100;
	cout << "p1.m_A = " << p1.m_A << endl;
	Person p2;
	p2.m_A = 200;
	cout << "p1.m_A = " << p1.m_A << endl; //共享同一份数据
	cout << "p2.m_A = " << p2.m_A << endl;
	//2、通过类名
	cout << "m_A = " << Person::m_A << endl;
	//cout << "m_B = " << Person::m_B << endl; //私有权限访问不到
}
int main() {
	test01();
	system("pause");
	return 0;
}

代码解释:上述代码我们主要验证了利用两种方式来访问静态成员变量,以及静态成员变量属于整个类,属于类的所有对象

1.3:静态成员函数

class Person
{
public:
	static void func()
	{
		cout << "func调用" << endl;
		m_A = 100;
		//m_B = 100; //错误,不可以访问非静态成员变量
	}
	static int m_A; //静态成员变量
	int m_B; // 
private:
	//静态成员函数也是有访问权限的
	static void func2()
	{
		cout << "func2调用" << endl;
	}
};
int Person::m_A = 10;
void test01()
{
	//静态成员变量两种访问方式
	//1、通过对象
	Person p1;
	p1.func();
	//2、通过类名
	Person::func();
	//Person::func2(); //私有权限访问不到
}
int main() {
	test01();
	system("pause");
	return 0;
}

代码解释:上述代码我们主要验证了利用两种方式来访问静态成员函数,利用对象访问和利用类名访问,以及静态成员函数只可以访问静态成员变量

⚠️⚠️⚠️:为什么不可以访问非静态成员?

⭐️因为没有this指针

1.4:总结特性

  1. 静态成员为所有类对象所共享,不属于某个具体的类实例
  2. 静态成员变量必须在类外定义,定义时不加static关键字
  3. 类静态成员类名::静态成员或者对象.静态成员来访问
  4. 静态成员函数没有隐含的this指针,不可以访问任何非静态成员
  5. 静态成员和类的普通成员也一样,也有三种访问权限,也可以有返回值。

1.5:试题示例

❓实现一个类,计算程序中创建了多少个类对象

class A
{
public:
	A(){
		++_count1;
	}
	A(const A& aa){
		++_count2;
	}
	// 成员函数也可以是静态,static成员函数没有this指针
	static int GetCount1(){
		return _count1;
	}
	static int GetCount2(){
		return _count2;
	}
//private:
	// 静态成员变量属于整个类,所以类的所有对象
	static int _count1;
	static int _count2; // 声明
};
// 定义
int A::_count1 = 0;
int A::_count2 = 0;
A Func(A a)
{
	A copy(a);
	return copy;
}
int main()
{
	A a1;
	A a2 = Func(a1);
	cout << a1._count1 << endl;
	cout << a2._count1 << endl;
	cout << a1._count2 << endl;
	cout << a2._count2 << endl;
	cout << A::_count1 << endl;
	cout << A::_count2 << endl;
	cout << a1.GetCount1() << endl;
	cout << a2.GetCount2() << endl;
	cout << A::GetCount1() << endl;
	cout << A::GetCount2() << endl;
	system("pause");
	return 0;
}

1
1
3
3
1
3
1
3
1
3
请按任意键继续. . .

1.6:C++11成员初始化新玩法

class B
{
public:
	B(int b = 0)
		:_b(b)
	{}
	int _b;
};
class A
{
public:
	//A()//其实是编译器自己生产的默认构造函数用缺省值初始化
	//	:a(10)
	//	, b(20)
	//	, p((int*)malloc(4))
	//{}
	void Print()
	{
		cout << a << endl;
		cout << b._b << endl;
		cout << p << endl;
		cout << n << endl;
	}
private:
	// 非静态成员变量,可以在成员声明时给缺省值。
	int a = 10;
	B b = 20;//单参数的构造函数,支持隐式类型的转换
	int* p = (int*)malloc(4);
	static int n;
	//非静态成员变量定义在构造函数
	//静态在类外
};
int A::n = 0;
int main()
{
	A a;
	a.Print();
	system("pause");
	return 0;
}

二:友元

在程序里,有些私有属性 也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术

友元的目的就是让一个函数或者类 访问另一个类中私有成员

友元的关键字为friend

友元分为:

  • 友元函数
  • 友元类

友元的三种实现:

全局函数做友元

类做友元

成员函数做友元

2.1:全局函数做友元

⭐️说明:友元函数可以直接访问类的私有成员,它是定义在类外部的普通成员函数,不属于任何类,但需要在类的内部声明,声明的时候需要加friend关键字。

class Building
{
	//告诉编译器 GoodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容
	friend void goodGay(Building * building);
public:
	Building(){
		this->m_SittingRoom = "客厅";
		this->m_BedRoom = "卧室";
	}
public:
	string m_SittingRoom; //客厅
private:
	string m_BedRoom; //卧室
};
void goodGay(Building * building){
	cout << "好基友正在访问: " << building->m_SittingRoom << endl;
	cout << "好基友正在访问: " << building->m_BedRoom << endl;
}
void test01(){
	Building b;
	goodGay(&b);
}
int main(){
	test01();
	system("pause");
	return 0;
}

代码解释:如上述代码中,我们需要告诉编译器 goodGay全局函数 是 Building类的好朋友,可以访问类中的私有内容

2.2:类做友元

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类的非公有成员。

  • 友元关系是单向的,不具有交换性。
  • 友元关系不可以传递。如果B是A的友元,C是B的友元,但是不可以说C是A的友元。

代码示例:

class Building;
class goodGay
{
public:
	goodGay();
	void visit();
private:
	Building *building;
};
class Building
{
	//告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容
	friend class goodGay;
public:
	Building();
public:
	string m_SittingRoom; //客厅
private:
	string m_BedRoom;//卧室
};
Building::Building(){
	this->m_SittingRoom = "客厅";
	this->m_BedRoom = "卧室";
}
goodGay::goodGay(){
	building = new Building;
}
void goodGay::visit(){
	cout << "好基友正在访问" << building->m_SittingRoom << endl;
	cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void test01(){
	goodGay gg;
	gg.visit();
}
int main(){
	test01();
	system("pause");
	return 0;
}

代码解释:如上述代码中,我们需要告诉编译器 告诉编译器 goodGay类是Building类的好朋友,可以访问到Building类中私有内容

2.3:成员函数做友元

一个类的成员函数做另一个类的友元。

代码示例:

class Building;//提前声明
class goodGay
{
public:
	goodGay();
	void visit(); //只让visit函数作为Building的好朋友,可以发访问Building中私有内容
	void visit2(); 
private:
	Building *building;
};
class Building
{
	//告诉编译器  goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容
	friend void goodGay::visit();
public:
	Building();
public:
	string m_SittingRoom; //客厅
private:
	string m_BedRoom;//卧室
};
Building::Building(){
	this->m_SittingRoom = "客厅";
	this->m_BedRoom = "卧室";
}
goodGay::goodGay(){
	building = new Building;
}
void goodGay::visit(){
	cout << "好基友正在访问" << building->m_SittingRoom << endl;
	cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void goodGay::visit2(){
	cout << "好基友正在访问" << building->m_SittingRoom << endl;
	//cout << "好基友正在访问" << building->m_BedRoom << endl;
}
void test01(){
	goodGay  gg;
	gg.visit();
}
int main(){  
	test01();
	system("pause");
	return 0;
}

代码解释:如上述代码中,我们需要告诉编译器 goodGay类中的visit成员函数 是Building好朋友,可以访问私有内容

三:内部类

3.1:概念

概念:如果一个类定义在另一个类的内部,这个类就叫内部类。注意此时的内部类是一个独立的类,它不属于外部类。更不可以通过外部类的对象去调用内部类。外部类对内部类没有任何的访问权限。

⚠️下面我们看一段代码:

// 内部类
class A
{
private:
	static int k;
	int h;
public:
	// 内部类
	class B // B天生就是A的友元
	{
	public:
		void foo(const A& a)
		{
			cout << k << endl;//OK
			cout << a.h << endl;//OK
		}
	private:
		int _b;
	};

	// A不是B的友元
	
};
int A::k = 1;
int main()
{
	A aa;
	cout << sizeof(A) << endl;
	A::B bb;
	return 0;
}

代码解释:如上述代码中,对于此处的内部类,B天生就是A的友元,所以在B类中可以访问A类的私有成员,但是A不是B的友元。如果内部类是公有属性的话,我们还可以实例化内部类对象。

3.2:特性

⭐️⭐️⭐️特性:

  • 内部类可以定义在外部类的public、protected、private都是可以的。
  • 注意内部类可以直接访问外部类中的static、枚举成员,不需要外部类的对象/类名。
  • sizeof(外部类) = 外部类,和内部类没有任何关系。

到此这篇关于C++类与对象深入之静态成员与友元及内部类详解的文章就介绍到这了,更多相关C++类与对象内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++类与对象深入之静态成员与友元及内部类详解

本文链接: https://lsjlt.com/news/151043.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++类与对象深入之静态成员与友元及内部类详解
    目录一:静态成员1.1:静态成员分类1.2:静态成员变量1.3:静态成员函数1.4:总结特性1.5:试题示例1.6:C++11成员初始化新玩法二:友元2.1:全局函数做友元2.2:类...
    99+
    2024-04-02
  • C++深入探究类与对象之友元与运算符重载
    目录友元1 全局函数做友元2 类做友元3 成员函数做友元运算符重载1 加号运算符重载2 左移运算符重载3 递增运算符重载4 赋值运算符重载5 关系运算符重载6 函数调用运算符重载友元...
    99+
    2024-04-02
  • C++类的静态成员变量与静态成员函数详解
    目录1、类的静态成员变量2、静态成员函数总结1、类的静态成员变量 C++类的静态成员变量主要有以下特性: 1.静态成员变量需要类内定义,类外初始化 2.静态成员变量不依赖于类,静态成...
    99+
    2024-04-02
  • C++超详细讲解友元与内部类
    目录一.友元1.友元函数(1)引入原因(2)友元函数作用(3)友元函数特征2.友元类(1)解释(2)友元类特征二.内部类(不常用)1.概念2.特性 一.友元 友元分为: 友...
    99+
    2024-04-02
  • C++分析类的对象作类成员调用构造与析构函数及静态成员
    目录类对象作为成员静态成员定义和分类静态成员变量静态成员函数总结类对象作为成员 C++类中的成员可以是另一个类的对象,我们称该成员为 对象成员 例如: class Phone {} ...
    99+
    2024-04-02
  • Java内部类详解(含:成员内部类、局部内部类、匿名内部类、静态内部类)
    内部类是什么? 字面意思,在类的内部编写的类就叫内部类!即一个类的内部又完整的嵌套了另一个类结构,被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。 内部类是类的第五大成员→【提示:类的五大...
    99+
    2023-10-26
    jvm
  • 怎么理解C++类的静态成员变量与静态成员函数
    本篇内容介绍了“怎么理解C++类的静态成员变量与静态成员函数”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1、类的静态成员变量C++类的静态...
    99+
    2023-06-25
  • C++类与对象深入之引用与内联函数与auto关键字及for循环详解
    目录一:引用1.1:概念1.2:引用特性1.3:常引用1.4:使用场景1.5:引用和指针的区别二:内联函数2.1:概念2.2:特性2.3:面试题三:auto关键字3.1:auto简介...
    99+
    2024-04-02
  • C++类与对象深入之构造函数与析构函数详解
    目录对象的初始化和清理一:构造函数1.1:构造函数的特性1.2:构造函数的分类二:析构函数2.1:概念2.2:特性三:拷贝构造函数3.1:概念3.2:特性3.3:拷贝构造函数调用时机...
    99+
    2024-04-02
  • C++深入讲解类与对象之OOP面向对象编程与封装
    目录1.面向对象编程2.面向过程性编程和面向对象编程3.类的引入4.类的定义4.1类的两种定义方式4.1.1声明和定义全部放在类体中4.2.2.声明和定义不放在类体中5.类的访问限定...
    99+
    2024-04-02
  • C++类与对象深入之运算符重载与const及初始化列表详解
    目录一:运算符重载相等运算符重载赋值运算符重载小于运算符重载二:const成员const修饰类的成员函数三:cin、cout重载四:初始化列表构造函数赋初值初始化列表explicit...
    99+
    2024-04-02
  • 详解Python中的静态方法与类成员方法
    前言 因为Python的水平目前一直是处于能用阶段,平时写的脚本使用的Python的写法也比较的简单,没有写过稍微大一点的项目。对Python中的类,类之间的组织关系,整个项目中类之间如何耦合还缺乏认识。打...
    99+
    2022-06-04
    方法 静态 详解
  • C++类的对象作类成员调用构造、析构函数及静态成员实例分析
    这篇文章主要介绍了C++类的对象作类成员调用构造、析构函数及静态成员实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C++类的对象作类成员调用构造、析构函数及静态成员实例分析文章都会有所收获,下面我们一起...
    99+
    2023-06-30
  • C++学习笔记之类与对象详解
    目录前言:1.访问限定符:【问题】C++中 struct和class的区别是什么?2.封装【问题】在类和对象的阶段,我们只研究类的封装特性,那什么是封装呢?3.类的定义与声明【问题】...
    99+
    2024-04-02
  • 深入剖析Python类与对象的内部运作机制
    类与对象 在Python中,类是对象的蓝图,它定义了对象的属性和方法,而对象是类的实例,它具有类的所有属性和方法。 class Person: def __init__(self, name, age): self.na...
    99+
    2024-02-22
    Python 对象 方法 属性 继承 多态
  • C++深入探究类与对象之对象模型与this指针使用方法
    目录C++对象模型和this指针1 成员变量和成员函数分开存储2 this指针概念3 空指针访问成员函数4 const修饰成员函数C++面向对象的三大特性为:封装、继承、多态 C++...
    99+
    2024-04-02
  • C++深入探索类和对象之封装及class与struct的区别
    目录封装的意义访问权限class和struct的区别成员属性私有案例练习封装的意义 封装是C++三大面向对象之一 意义: 1、设计类的时候,属性和行为写在一起,表现事物 2、类在设计...
    99+
    2024-04-02
  • C++类与对象之运算符重载详解
    目录运算符重载加号运算符重载左移运算符重载递增运算符重载递减运算符重载赋值运算符重载关系运算符重载函数调用运算符重载总结运算符重载 运算符重载概念:对已有的运算符重新进行定义,赋予其...
    99+
    2024-04-02
  • C++中对象与类的详解及其作用介绍
    目录什么是对象面向过程 vs 面向对象面向过程面向对象什么是类类的格式类的成员函数函数访问权限方法一方法二方法三inline 成员函数什么是对象 任何事物都是一个对象, 也就是传说中...
    99+
    2024-04-02
  • C++ 成员函数详解:对象方法的重载与多态性
    成员函数重载允许为同一类定义同名函数,区分依据是参数和返回值类型。多态性允许派生类对象通过继承基类方法表现出不同的行为,当基类引用指向派生类对象时,调用基类方法将执行与对象类型匹配的派生...
    99+
    2024-04-30
    c++ 成员函数
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作