C++类的复习笔记

200 阅读6分钟

接上一篇文章# C++学习笔记之引用【详细版】

这一章我们来看C++中的类!


本文已参与[新人创作礼]活动,一起开启掘金创作之路。


1.什么是类

类是对现实生活中一类具有共同特征的事物的一种抽象。

C++ 支持面向对象程序设计:

  • 类是一种可以被用户自定义的数据类型
  • 类的实例称为对象
  • 类将数据和函数(方法)封装在一起
  • 类是实现信息封装的基础
  • 类中的数据和方法称为类的成员
  • 每个类包含数据说明和一组操作数据或传递消息的函数

再来看看思维导图:

类的特性.png


2.如何定义类

类的关键字为:class

语法:

class class_name {
	Modifier:
		type var_name;
		type func(){  };
};  //这里有个分号,请不要忘记

解释:

  • class :类的关键字
  • class_name:类的名字(符合标识符规范即可)
  • Modifier:类的修饰符(即类的访问属性,一共有三种,本章后面会讲)
  • type var_name;:类中的变量
  • type func(){ };:类的成员函数(方法)

3.定义类的对象

上述已经提到,类是对现实生活中一类具有共同特征的事物的一种抽象。

这么理解,定义一个类就是绘制蓝图,而我们根据这个蓝图来创建若干个实例。

比如我们定义一个学生类,这个类里面可以有学生的学号,性别,班级号等等,而我们根据这个学生类就可以来创建若干个对象,即实例。

来看一段代码:

#include <iostream>
using namespace std;
//定义一个学生类 
class Student {
	int id_number;
	int gender;
};
//创建学生类的对象 
int main() {
	Student stu_1;
	Student stu_2;
}

在上述代码中,对象stu_1stu_2都有各自的数据成员。


4.访问类对象

我们通过.成员运算符来访问类对象的成员 注意!:

  • 必须在public修饰符的修饰下,才能在类的外部访问对象的成员
  • 私有的成员和受保护的成员不能直接使用成员访问运算符来访问
#include <iostream>
using namespace std;
//定义一个学生类 
class Student {
public:
//该修饰符下的成员,在类的外部是可访问的
	int id_number;
	//成员函数的定义 
	int get_id_number()
	{
		return id_number;
	}
};
int main() {
	Student stu_1;//创建学生类的对象
	
	stu_1.id_number = 1001;//初始化对象
	 
	cout<<"该学生的学号为:"<<stu_1.get_id_number();//调用成员函数 
}

5.类的成员函数

一般成员函数的定义会在类外面,但也可以直接在类内部定义。前者在定义时必须明类的名称,而后者一般为一些短小的函数(5行以内),也会被默认为内联函数。


5.1.在类内定义成员函数

看段代码:

#include <iostream>
using namespace std;
class Circle {
public:
	void set_r(int x)
	{
		r = x;
	}
	double get_area()
	{
		return PI*r*r;
	}
private:
	double r; 
	const double PI = 3.1415;
};
int main() {
	Circle c;
	c.set_r(3.22);
	cout<<"圆c的面积为:"<<c.get_area();
}
  • 在C++中,我们一般将类的定义写在一个头文件里面
  • 函数定义不能放在头文件里面
  • 这是因为伴随着在不同程序文件中的包含展开,函数会被编译多次
  • 但是内联函数是可以写在头文件里头的
  • 因为内联函数是作为全局静态属性在源程序里扩展
  • 重点来了,类中定义的成员函数会被默认为内联函数(即便没有使用 inline 标识符)
  • 所以在头文件里面,我们可以在类的内部定义成员函数

5.2.在类外定义成员函数

  • 在类外定义成员函数的语法为:
  • 返回类型 类名::函数名(形参列表) {函数体}

看段代码:

date.h

class Date {
public:
	void set_date(int, int, int);
	void print_day();
private:
	int day, month, year;
};

date.cpp

#include <iostream>
using namespace std; 
#include "date.h"

void Date::set_date(int y, int m, int d) {
	year = y;
	month = m;
	day = d;
	
}

void Date::print_day() {
	cout <<"您设置的日期为:"
		 << year << "/" 
		 << month << "/" 
		 << day;
}


test.cpp

#include <iostream>
#include "date.h"
using namespace std;
int main() {
	Date day_1;
	day_1.set_date(2022, 03, 22);
	day_1.print_day();
	return 0;
}

运行结果如下:

您设置的日期为:2022/3/22

分析:

  • 在类外定义成员函数时,我们应该加上类名和作用域区分符::
  • 类名加作用域区分符可以起到区分的效果,即知道该成员函数属于哪一个类
  • 比如上述代码中,数据成员day实际上全名为Date::day
  • 没有类名的函数叫做非成员函数

5.3.小结

事实上,在开发中,我们会把类的成员函数的声明和定义分开写。并在使用时(主函数中)导入类的头文件。

  • 一般我们会把类的成员函数的声明写在头文件里面(.h),然后将成员函数的定义写在另一个源程序里(.cpp

  • 这就有点像我们使用标准库里的函数一样。

  • 注意!导入(包含)自己编写的头文件时,应该使用双引号" ",而不是 < >

备注:

  • 有些时候,我们会在一个函数里定义一个类(虽然并不多见)
  • 在函数中定义的类叫做局部类
  • 局部类的成员函数必须得在类内部定义

6.类的访问修饰符

先来看一张思维导图:

访问修饰符.png

示例:

class A {
public:
	// 公有成员
protected:
	// 受保护成员
private:
	// 私有成员
};

  • 在类的作用域中,任何一个成员都能访问同一个类的其他成员,一个类的全体成员是一个整体。
  • 在类的作用域之外,其他的类若想访问这个类的成员,就会受到访问权限的制约。
  • 而一个类的访问权限就是由访问修饰符所决定。
  • 也就是说,我们将一个类的数据与功能给封装起来,对访问进行限制。

6.1.public

  • public修饰下的成员,在类外部(普通函数或其他类的成员函数)可以访问。
  • 我们不用设置成员函数就可以直接设置和获取公有成员的值。
  • 事实上,当我们在开发中,想要使用某个类,就必须了解类的公有成员,去了解每个公有成员的参数,用法等等。
  • 这就像看电视,我们只需学会如何遥控器用法即可,而不用去了解电视机的底层原理或内部构造。这种通过接口限制的方法,是类的一大特点。

6.2.protected

  • 当我们把类的成员设置为受保护的,此时,在类的外部就不能对类的成员进行访问。
  • 将类的成员设置为受保护的,其原因主要是不让外部访问,相对于外部函数,保护类的内部数据成员不被接触。
  • C++类的保护机制使得编写的程序更加可靠且易维护
  • 一般保护成员是在继承方面可以起作用。
  • 比如:protected成员在子类中是可访问的。

6.3.private

  • private成员变量或函数在类的外部是无法访问,无法查看的。
  • 只有类和友元函数可以访问私有成员。
  • 如果不写访问修饰符,则类的成员属于私有成员,即private