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

目录
  • 一:静态成员
    • 1.1:静态成员分类
    • 1.2:静态成员变量
    • 1.3:静态成员函数
    • 1.4:总结特性
    • 1.5:试题示例
    • 1.6:C++11成员初始化新玩法
  • 二:友元
    • 2.1:全局函数做友元
    • 2.2:类做友元
    • 2.3:成员函数做友元
  • 三:内部类
    • 3.1:概念
    • 3.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的友元
	/*void Print(const B& b)
	{
	b._b = 0;
	}*/
};
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++类与对象内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++的友元和内部类你了解吗

    目录 友元函数 案例 友元类 内部类 总结 友元分为:友元函数 和 友元类 友元提供了一种突破封装的方式,有时提供了便利.但是友元会增加耦合度,破坏了封装,所以友元不宜多用. 友元函数 友元函数 可以 直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加 friend 关键字. 友元函数可访问类的私有和保护成员,但不是类的成员函数 友元函数不能用 const 修饰 友元函数可以在类定义的任何地方声明,不受类访问限定符限制 一个函数可以是多个类的友元函

  • C++超详细讲解友元与内部类

    目录 一.友元 1.友元函数 (1)引入原因 (2)友元函数作用 (3)友元函数特征 2.友元类 (1)解释 (2)友元类特征 二.内部类(不常用) 1.概念 2.特性 一.友元 友元分为: 友元函数 和 友元类 友元提供了一种突破封装的方式,有时提供了便利.但是友元会增加耦合度,破坏了封装,所以友元不宜多用. 1.友元函数 (1)引入原因 operator<<:因为cout 的 输出流对象和隐含的 this 指针在抢占第一个参数的位置 . this 指针默认是第一个参数也就是左操数了.但是实

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

    目录 一:静态成员 1.1:静态成员分类 1.2:静态成员变量 1.3:静态成员函数 1.4:总结特性 1.5:试题示例 1.6:C++11成员初始化新玩法 二:友元 2.1:全局函数做友元 2.2:类做友元 2.3:成员函数做友元 三:内部类 3.1:概念 3.2:特性 一:静态成员 静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员.C++里面尽量用静态成员变量代替全局变量. 1.1:静态成员分类 1️静态成员变量: 所有对象共享同一份数据 在编译阶段分配内存 类内声明,

  • C++ 类中有虚函数(虚函数表)时 内存分布详解

    虚函数表 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的.简称为V-Table.在这个表中,主是要一个类的虚函数的地址表,这张表解决了继承.覆盖的问题,保证其容真实反应实际的函数.这样,在有虚函数的类的实例中这个表被分配在了这个实例的内存中,所以,当我们用父类的指针来操作一个子类的时候,这张虚函数表就显得由为重要了,它就像一个地图一样,指明了实际所应该调用的函数. 这里我们着重看一下这张虚函数表.C++的编译器应该是

  • C++类继承之子类调用父类的构造函数的实例详解

    C++类继承之子类调用父类的构造函数的实例详解 父类HttpUtil: #pragma once #include <windows.h> #include <string> using namespace std; class HttpUtil { private: LPVOID hInternet; LPVOID hConnect; LPVOID hRequest; protected: wchar_t * mHostName; short mPort; string send

  • python类的方法属性与方法属性的动态绑定代码详解

    动态语言与静态语言有很多不同,最大的特性之一就是可以实现动态的对类和实例进行修改,在Python中,我们创建了一个类后可以对实例和类绑定心的方法或者属性,实现动态绑定. 最近在学习python,纯粹是自己的兴趣爱好,然而并没有系统地看python编程书籍,觉得上面描述过于繁琐,在网站找了一些学习的网站,发现廖雪峰老师的网站上面的学习资源很不错,而且言简意赅,提取了一些python中的重要的语法和案例.重要的是可以在线测试python的运行代码,缺点就是没有系统的看python的书籍,不能及时的将

  • Python对象中__del__方法起作用的条件详解

    对象的__del__是对象在被gc消除回收的时候起作用的一个方法,它的执行一般也就意味着对象不能够继续引用. 示范代码如下: class Demo: def __del__(self): print("calling __del__") obj = Demo() del obj 程序执行结果如下: grey@DESKTOP-3T80NPQ:/mnt/e/01_workspace/02_programme_language/03_python/03_OOP/2017/08$python

  • Vue实例的对象参数options的几个常用选项详解

    一. 新建一个Vue实例可以有下列两种方式: 1.new一个实例 var app= new Vue({ el:'#todo-app', // 挂载元素 data:{ // 在.vue组件中data是一个函数,要写成data () {}这种方式 items:['item 1','item 2','item 3'], todo:'' }, methods:{ // 方法成员 rm:function(i){ this.items.splice(i,1) } } }) // 之后再 export def

  • vue 绑定对象,数组之数据无法动态渲染案例详解

    项目场景: 黑马vue项目管理实战,获取商品分类,展开栏的标签页中修改修改数据属性 问题描述: 在本该点击+new tag这个标签页时弹出一个input框让用户输入需要添加的属性 结果点击时却不能立马渲染 async getParametersList() { this.cat_id = this.currentSelect[this.currentSelect.length - 1]; const { data: res } = await this.$http.get( `categorie

  • Java嵌套类和内部类详解

    一.什么是嵌套类及内部类? 可以在一个类的内部定义另一个类,这种类称为嵌套类(nested classes),它有两种类型: 静态嵌套类和非静态嵌套类.静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为 内部类(inner).嵌套类从JDK1.1开始引入.其中inner类又可分为三种: 其一.在一个类(外部类)中直接定义的内部类:     其二.在一个方法(外部类的方法)中定义的内部类;     其三.匿名内部类. 下面,我将说明这几种嵌套类的使用及注意事项. 二.静态嵌套类 如下所示代

  • C++静态成员函数和this指针详解

    目录 静态成员 1.静态成员变量 2.静态成员函数 成员变量和成员函数分开存储 this 指针 空指针访问成员函数 总结 静态成员 静态成员就是在成员变量和成员函数前加上关键字static,称为静态成员 静态成员分为: 1.静态成员变量 所有对象共享同一份数据 在编译阶段分配内存 类内声明,类外初始化 示例: #include<iostream> using namespace std; class Person { public: static int m; // 所有对象共享同一份数据 }

  • iOS对象指针和基础数据类型的强转详解

    本文主要介绍了iOS中对象指针和基础数据类型如何进行强转,下面话不多说,直接来看示例详解. 一.对象指针的强转: UIView *view = [UIView new];//new一个UIView类的对象 UILabel *label = (UILabel *)view;//强转成UILabel指针 label.text = @"123";//给label的text属性赋值(调用label的setText方法) 上述代码会产生崩溃,崩溃信息如下: -[UIView setText:]:

随机推荐