C++_类的初级学习(没学过类的同学来哟,将你对类的概念引入门,无压力哈哈哈哈啊哈)

一、类的概述

类简介:

C++中通过定义一个来定义自己的数据结构。(没错,它就是一个数据结构哈哈哈哈,别以为只有class声明才是类啊,我                                                                                        struct也行的)

一个类定义了一个类型,以及与其关联的一组操作。

类的基本思想是数据抽象封装

数据抽象:一种依赖于接口和实现分离的编程技术

接口:用户所能执行的操作

类的实现:包括类的数据成员、负责接口实现的函数体以及定义类所需要的各种私有函数

封装:实现类的接口和实现的分离

类想要实现数据抽象和封装,需要首先定义一个抽象数据类型。

这就涉及到这样几个问题

(1)基础问题:定义格式是什么、定义在哪(一般定义在头文件)

(2)定义这个类是用来干什么的?

(3)怎样去实现这个类?

那么我来举个例子

我需要定义一个类,它用来记录书的交易情况

/*
定义一个实现书店交易的类
它要实现表示一本书的总销售额、售出册数、平均售价
那么要是实现这个类,得先定义其数据成员,然后是类所能提供得接口(实现类所需要的操作)
然后开始实现接口
*/
struct Sales_date
{
	std::string isbn() const { return bookNo; }//返回ISBN编号
	Sales_date& combine(const Sales_date);     //将一个Sales_date对象加到另一个对象上去
	double avg_price() const;                  //计算均价
	std::string bookNo;     //ISBN编号
	unsigned units_sold = 0;//销售数量
	double revenue = 0.0;   //销售总额
};
//Sale_date 的非成员接口函数
Sales_date add(const Sales_date&, const Sales_date&); //执行两个Sales_date对象的加法
std::ostream &print(std::ostream&, const Sales_date&);//将Sales_date对象输出到ostream上
std::istream &read(std::ostream&, const Sales_date&); //从ostream上读入到Sales_date对象

(不用在意我定义的顺序,编译器会先编译类内的成员的声明,然后在处理函数体)

以上的接口函数中 isbn()在类内定义,combine和avg_price在类外定义。

类内定义类似于内联函数(inline)。

而关于该对象的非成员函数,我们选择定义在类外。

至此,我们就定义好了一个类。关于类的使用,我们始终要记得以下几点

1.类名是什么

2.它在哪里定义

3.它支持什么操作

二、类的接口函数

先引入先this这个东西的概念

(为节省墨水,我就不多举例子了,还是用上面类的定义。)

类内函数isbn()相当于隐式的内联函数

我们使用该函数时。一般是这个样子 test.isbn()。使用点操作符去访问test对象的isbn成员,然后调用它。

test对象执行了isbn()操作,实际上相当于隐式的返回test.bookNo。

But问题来了,为啥它返回的就是test的bookNo成员嘞?(终于要引出来了)

没错!!!就是因为this

因为成员函数通过一个名为this的额外隐式参数来访问调用它的那个对象,当我们调用一个成员函数,用请求该函数的对象地址初始化this,例如,如果调用test.isbn()。

可以看作为 Sales_date::isbn(&test)。

敞亮了,传入了test的指针实参给形参this。那么this就是指向test的指针。

因此this就是指向调用函数的对象的指针

回归问题,其实isbn是隐式的使用了this,那么isbn中的return bookNo,其实就是隐式的this—>bookNo

再敞亮点,咱们把this替换成实参,上式不就是test.bookNo嘛。

在类内是允许使用this指针的。尽管没必要,但是我们依旧可以改写isbn()达到相同的效果

std::string isbn() const { return this->bookNo};

关于上面

要解释的也就是那个const了(加它干啥呀,挠挠我掉发的头)

它是修饰this属性的,给this加个底层const

this是一个指向类类型非常量版本的常量指针。咋理解

我这样解释,我上面的this 就是 Sales_data *const类型。

它有一个顶层const限制,也就是说,它的内容(也可以说是它本身)不可被修改

但是它没有底层const限制,也就是说它指向的对象的内容是非const型的(可以被修改)

那么我要一个常量的对象使用isbn ,如果没有那个const修饰就会报错。。。

试图将一个const指针赋给一个非const的指针。这个const指的是底层const。

为了函数的灵活性,既能够被常量对象调用,也能被非常量对象调用。

来个全套const服务。

(但是别入坑啊,有时this作为左值的时候还是不需要底层const的。别搞错了应用场景)

接下来this的性质讲解交给这位哥

https://blog.csdn.net/jx232515/article/details/52759127

一条龙服务有没有,带你从坑跳坑。

接下来实现我们的接口函数。(一、中只是声明,没有实现函数体)

using namespace std;
ostream &print(std::ostream &os, const Sales_data &rhs)//输出书的编号 数量 总数 平均价格
{
	os << rhs.isbn() << " " << rhs.units_sold << " " 
		<< rhs.revenue << " " << rhs.avg_price();
	return os;
}
istream &read(std::istream& is, Sales_data& rhs)//输入书的编号 数量 价格
{
	double price = 0;
	is >> rhs.bookNo >> rhs.units_sold >> price;
	rhs.revenue += price * rhs.units_sold;
	return is;
}
double Sales_data::avg_price() const              //求平均价格
{
	if (units_sold)
		return revenue / units_sold;
	else
		return 0;
}

Sales_data& Sales_data::combine(const Sales_data &rhs)
{
	units_sold += rhs.units_sold;//把rhs的成员加到this对象的成员上去
	revenue += rhs.revenue;
	return *this;                //返回调用该函数的对象
}

Sales_data add(const Sales_data &lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;
	sum.combine(rhs); //把rhs的数据成员加到sum当中
	return sum;
}

int main(void)
{
	Sales_data total;     //保存当前求和的结果的变量
	if (read(cin, total)) //读入第一笔交易到total
	{
		Sales_data trans;
		while (read(cin, trans))//读入新的交易到trans
		{
			if (total.isbn() == trans.isbn())//如果新读入书编号和前面的相同
				total.combine(trans);    //执行相加操作
			else
			{
				print(cout, total) << endl; //不相同
				total = trans;              //处理下一本书
			}
		}
		print(cout, total) << endl;                 //输出最后的交易
	}
	else                                                //没有任何交易
	{
		cerr << "No data?!" << endl;                //通知用户
	}

	system("pause");
	return 0;
}

至此类的一个框架搭好了,下篇我们继续向下探究类哈哈哈哈。

猜你喜欢

转载自blog.csdn.net/lovely_ke/article/details/82936099