类的学习笔记

类的概念

C++拓展了结构体的概念,其可以包括函数作为自己的成员函数,结构体中的书数据称为数据成员。这样的结构体类型称为类,这种结构体变量称为对象。
例如:

struct data{
	string productno;
	double price;
	unsigned unitsold;
	//数据成员的声明和定义 (均为public类型) 
	//函数成员的声明和定义
	double total()
	{
		return price * unitsold;//在同一类中 函数可以自由访问类中的数据成员	(无需再次声明)(之后可以用this指针解释)
	} 
	void read()
	{
		cin >> product >> price >> unitsold;//同上 
	}
	void print()
	{
		cout << productno << price << unitsold << endl;
	}
};//类的类型定义结束 

类中成员的调用

类中函数的使用通过成员运算符来实现 如:

int main()
{
	data s;//先声明一个data类的对象 
	s.read();
	s.print();//调用对象中的函数 
	return 0;
} 

类中函数的类外定义

类中的函数可以不在类内进行定义,可以在类外进行定义 如:

struct data{
	string productno;
	double price;
	unsigned unitsold;
	//数据成员的声明和定义 (均为public类型) 
	//函数成员的声明
	double total(); 
	void read();
	void print(); 
};//类的类型定义结束

//类的函数成员的类外定义 要使用::指明所定义的函数所归属的类 
double data::total()
{
	return price * unitsold;
}
void data::read()
{
	cin>> product >> price >> unitsold;
}

void data::print()
{
	cout << product << price << unitsold;
}//所使用类内的变量不作为参数传入函数即可自由使用 但 如果要使用类外的变量则要使用参数列表来传入 

使用这种方法的主要目的就是将定义和声明分开为两个文件 声明作为.h文件,实现作为同名的.cpp文件 存储为同一个项目内

包含守卫

类定义的头文件可能被重复包含,就会引发编译错误,利用包含守卫可以保证每一个头文件只被包含一次。

#ifndef Header_Flag//header_flag 通常采用头文件的名字作为区分 
#define Header_Flag
//类型定义
#endif

使用例子:

//salesdata.h 的声明文件内
#ifndef Salesdata.h
#define Salesdata.h

#include<string.h>
struct SalesData{
	std::string productno;
	double price;
	unsigned int unitsold;
	
	double totalRenvnue;
	void read();
	void print();
}; //注意这是一个类的声明 (类中的函数仅有声明部分 没有定义部分) 
#endif 

访问权限

访问权限的设定由类内的限定符号规定

struct 类的名字{
	public:
		//公有成员声明
		//公有成员可以在程序的任何函数或类中自由访问 
	private:
		//私有成员声明
		//私有成员只能由类自己的成员函数或友元访问 需要隐藏的信息应设置为私有成员类型 
	protected:
		//被保护成员声明 
		//可以被自己的成员函数 友元 派生类成员访问 
}; 

类的成员函数可以访问类中的任何元素 包括公有和私有
类外的操作只能访问类中的公有元素 不能 访问私有元素 且不能直接通过成员操作符访问私有元素
当不确定如何设置某一个成员的可访问性时 经验做法是采用最严格的可行访问级别 通常来说多隐藏好于少隐藏

类和对象

将数据和操作捆绑在一起,并加上访问控制,称为对象的封装
外部程序通过类接口中提供的操作访问对象中数据称为向对象发送信息
类是一种类型 对象是这种类型的变量 发送消息就是调用成员函数

引入新的关键字class来定义类 (大致用法和struct相同,但是定义上有所区别,struct定义的类默认访问权限是public,class定义的类的默认访问权限是private)。

无数据成员的对象的大小至少为1 保证对象具有唯一的标志 可区分 每个对象都有唯一的地址

类的大小不详细叙述 简单的类的大小就是各个数据成员的大小的和 复杂的类的大小常使用边界对齐技术 对象的大小是机器字长的整数倍

this指针

每个成员函数都有一个隐含的参数 指向接受消息的对象 称为this指针 X类的this指针的类型是X* ,当一个对象的成员函数被调用时,this指针就指向该对象操作a的数据成员
this指针是一个常量 含有当前实施调用的对象的地址 不能改变this指针的值 也不可以取它的地址
解释为什么类内函数使用类内变量不用串参:

class X {
	int m;
	public :
		void setVal(int v)
		{
			m = v;
		}
};
//上下两中定义的方法均正确 
class X {
	int m;
	public:
		void setVal(int v)
		{	//显示使用this指针 
			this->m = v;//实际上是通过指针来实现对m的值的修改,即不用传参即可实现 
		}
};

特别的是 必须使用this指针的环境:

//1.区分和局部变量重名的数据成员
class X {
	int m;
	public:
		void setVal(int m)
		{
			this->m = m;//强调左值是类内的变量m不是传入的参数m 
		}
		//2.返回当前的对象(this指针的类型是顶层的const类型) 
		//调用一个类的成员时 类的地址会被绑定在this上 返回对象只能使用引用类型 
		X& add(const X &a)//传入的参数就是对象的引用类型 
		{
			m += a.m;//this内部就有当前对象的地址 
			return *this;//返回当前对象的一个引用类型 
			//解引用获取当前执行的对象 最终是返回对象的引用 
		}
		//3.判断两个对象是否相同
		void copy(const X& a)//传入a的引用 
		{
			if( this == &a)//对引用取地址取到被引用对象的地址 
			{
				return ;	 
			}	
			m = a.m;//修改本类中的m变量的值 
		} 
}; 
 

友元

前文可知 一个类的友元可以访问类的私有成员
c++使用friend作为关键字 如果要让非成员函数访问一个类中的私有数据 就要把这个非成员函数声明为friend友元。

class complex{
	....
	friend complex add(const complex &,const complex &);
	//在类中声明一次类的友元 简单地在原函数地声明地左边加上friend关键字即可
	//声明之后 add函数可以自由地使用complex类中地私有数据成员 
	....
}; 

友元不等于包含 类之间并没有交集 友元只是赋予了一个类访问另一个类的私有成员的权力而已 要调用的话 还是得采用传参的方式进行调用
如:

#include<bits/stdc++.h>
using namespace std;

class a{
	int i;
	public:
		friend class b;
		//如果没有友元的声明 则无法过编译 会弹出一个 i 是私有元的错误  即 b 中无法通过指针来之间调用 i 访问其值 
		void add(int a,int b)
		{
			i =  a + b;
		}
		void print(void)
		{
			cout<<"i = "<<i<<endl;
		}
};

class b{
	int j;
	public:
	void add(a* A)
	{
		j = A->i;
		//在这里可见直接访问了A的私有元 i 
	}
	void print(void)
	{
		cout<<"j = "<<j<<endl;
	}
}; 

int main(void)
{
	a A;
	b B;
	
	A.add(1,2);
	B.add(&A);
	
	A.print();
	B.print();
}

类之间的函数也是同样的道理 不能不传入类参数就直接调用另一个类的函数

friend不具有传递性 即:a是b的友元 b是c的友元 a不会自动成为c的友元
不具有继承性:基类的友元不会自动成为其派生类的友元
//2020 / 6 / 7 21:37(有点想划水了)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值