c++特殊成员

c++特殊成员

一、关键字explicit

explicit关键字:是禁止通过构造函数进行的隐式转换。声明为explicit的构造函数不能在隐式转换中使用。

注意:explicit用于修饰构造函数,防止隐式转换。是针对单个参数的构造函数(或者除了第一个参数外其余参数都有默认值的多参构造)而言。

造成影响如下图

**没加explicit时!**发生隐式转换
在这里插入图片描述

有加explicit时,无法隐式转换
在这里插入图片描述
原则上应该在所有的构造函数前加explicit关键字,当你有心利用隐式转换的时候再去解除explicit,这样可以大大减少错误的发生。

二、静态变量static

2.1 static介绍
优点:静态成员提供了一个同类对象的共享机制

一个类中可以有一个或多个静态成员变量,所有的对象都共享这些静态成员变量,都可以引用它。

为什么static变量要在内部申明,在类的外部定义?

	static 成员变量和普通 static 变量一样,都在内存分区中的全局数据区分配内存,到程序结束时才释放。
	这就意味着,static 成员变量不随对象的创建而分配内存,
	也不随对象的销毁而释放内存。而普通成员变量在对象创建时分配内存,在对象销毁时释放内存。

所以静态成员变量必须在类的内部申明,在类的外部定义。(C++17有了新写法,直接内联到类的内部)
2.2static成员函数与普通函数的区别

1、定义普通成员函数

		可以访问静态成员,但是这个函数只对静态成员进行操作,加上 static 语义更加明确。

2、定义静态成员函数

		在函数前面加上static,可以声明为静态函数

静态成员函数调用方式,有两种:

定义对象,通过对象去调用
不定义对象,直接通过类名去调用

实际代码操作如下

#include <iostream>
#include <string>
using namespace std;

class stu
{
public:
	stu()
	{
		name="nn";
	}
	static int A()
	{
		id = 666;
		return id;
	}
	int& getId()
	{
		return id;
	}
protected:
	static int id;
	string name;
};
//类内声明,类外初始化(在构造函数中也不行)
int stu::id=1;
int main()
{
	stu s;
	cout <<s.getId()<< endl;

	//调用static函数方法
	cout << s.A << endl;		//以对象调用
	cout << stu::A << endl;		//以类名限定调用
	system("pause");
	return 0;
}

三、C++面向对象模型和this指针

3.1 C++编译器是如何管理类、对象、类和对象之间的关系?

具体的说:具体对象调用类中的方法,那c++编译器是如何区分,是那个具体的类,调用这个方法那?

在C++类对象中的成员变量和成员函数是分开存储的
成员变量:

普通成员变量:	存储于对象中,与struct变量有相同的内存布局和字节对齐方式
静态成员变量:	存储于全局数据区中

成员函数:存储于代码段中。

将c++类转化为c语言写法代码解析

#include <iostream>
#include <string>
using namespace std;
//类中函数和静态变量不占内存
class stu
{
public:
	stu()
	{
		name = "nn";
	}
	static int A()
	{
		cout << "静态函数" << endl;
	}
	void show()
	{
		cout << name<<"普通函数" << endl;
	}
protected:
	static int id;
	string name;
};
int stu::id=66;

//解析成C语言方式
struct Stu
{
	string name="nn";
};
static int id=66;

void show(Stu* pthis)//this,为了防止被修改所以void show(Stu*const pthis);加上const
{
	cout<< pthis->name;
}
//因为静态函数中没有Stu* pthis指针,所以没有办法使用普通成员,只能使用静态变量
static int A()
{
	cout << id <<endl;
}

int stu::id = 1;
int main()
{
	stu s;
	Stu x;
	//c++
	s.show();
	stu::A();
	//转成c语言
	show(&x);
	A();

	system("pause");
	return 0;
}

3.2this指针

this 就是上面代码中的pthis,为了防止this指针被修改使用要加上const属性。

用处:它指向当前对象,通过它可以访问当前对象的所有成员。
所谓当前对象,是指正在使用的对象。

使用范围:this 只能用在类的内部,通过 this 可以访问类的所有成员,包括 private、protected、public 属性的。(若类成员函数的形参 和 类的属性,名字相同,通过this指针来解决。)
在这里插入图片描述
四、const成员变量

1、const成员函数

const成员变量注意!!

必须使用初始化参数列表初始化

不可以修改const成员变量

2、const 成员函数
定义:

	放在函数原型后面的是修饰的this指针所指向的对象,函数叫做const成员函数。

特点:

	在函数里面不能对对象的属性进行修改。const成员函数可以访问任何成员

普通函数可以调用const函数

3、const对象
特点:常对象只能访问常函数

实现代码如下

#include <iostream>
#include <string>
using namespace std;
//只能使用初始化参数列表


class stu
{
public:
	stu():id(2)
	{
		name = "nn";
	}
	int A()const
	{
		cout << "const函数" << endl;
	}
	//等价 const  stu* const this  = const this->show()
	void show() const//可以调用但是不能该
	{
		
		cout << name << "普通函数" << endl;
	}
	int getId()
	{
		
		cout << id;
		return id;
	}

protected:
	const int id;
	string name;
};

//const对象 只能调用const
int main()
{
	stu s;
	s.getId();
	const stu c;
	c.show();
	while (1);
	return 0;
}

4、friend成员变量

体现:赋予对象具有打破类的权限限定(在友元类和函数中)

1、什么是友元函数friend?

友元(friend)机制允许一个类将对其非公有成员的访问权授予指定的函数或者类,友元的声明以friend开始,
它只能出现在类定义的内部,友元声明可以出现在类中的任何地方:友元不是授予友元关系的那个类的成员,
所以它们不受其声明出现部分的访问控制影响。

友元函数是指:某些虽然不是类成员函数却能够访问类的所有成员的函数。就像好朋友一样,有钱一起花~

在函数中可以访问任意成员;

不属于类,在类外实现不需要作用域限定符,也不要friend。

在函数中,可以创建对象,使用任意的成员

友元类可以重载。
1、类内声明定义:调用函数一样。
2、类内声明,类外定义:调用函数一样,要传参,参是对象。

注意:在函数里面或者类里面才能赋予这种能力;
2、友元类

什么是友元类?
一个类 A 可以将另一个类 B 声明为自己的友元,类 B 的所有成员函数就都可以访问类 A 对象的私有成员。

将类B声明为A的友元类
申明之后即可在B类里访问A的私有成员

代码操作

#include <iostream>
#include <string>
using namespace std;
//打破限定符
//友元函数,破坏了类的封装性
class A
{
public:
	A(int money = 666666) :money(money) {}
	friend class B;		     //友元类的声明
private:
	friend void mo(A mm);     //友元函数声明
	int money;
};
class B
{
public:
	void show(A m)
	{
		m.money;
	}
private:
	
};

void mo(A mm)
{
	cout<< mm.money;  
}

int main()
{
	A zhang;
	mo(zhang);

	while (1);
	return 0;
}

5、类的成员函数指针

作者很懒只留下了代码
在这里插入图片描述

#include <iostream>
#include <string>
using namespace std;

class A
{
public:
	void show()
	{
		cout << "嘻嘻嘻" << endl;
	}
};
void AAA()
{
	cout << "h h h"<< endl;
}
int main()
{
	//普通函数指针
	void (*pt)();
	pt = AAA;
	pt();

	A a;
	A* n = new A;

	//成员函数指针的定义
	void (A::*xx)() = &A::show; 

	//2种调用方式
	(a.*xx)();
	(n->*xx)();
	while (1);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值