C++语言导学 第二章 用户自定义类型 - 2.3 类

第二章 用户自定义类型

2.3 类

将数据说明与其操作分离开来有其优势,例如我们可以以任意方式使用数据。但对于用户自定义类型来说,为了具备“真正的类型”所需的所有性质,在其表示形式和操作之间建立紧密的联系是很有必要的。特别是,我们通常希望保持数据表示对用户不可见,从而实现易用性、保证数据使用的一致性以及允许设计者未来改进数据表示。为此,我们必须将类型的接口(所有人均可使用)与其实现(可访问对外部不可见的数据)分离开来。在C++中,实现上述目的的语言机制称为类(class)。类含有一系列成员(member),它可以是数据、函数或者类型。类的public成员定义了接口,private成员则只能通过接口访问。例如:

class Vector{
public:
	Vector(int s):elem{new double[s]}, sz{s}{}		//构造一个Vector
	double& operator[](int i){return elem[i];}		//使用下标访问元素
	int size(){return sz;}
private:
	double* elem;		//指向元素的指针
	int sz;				//元素数目
};

在此基础上,我们可以定义新类型Vector的一个变量:

Vector v(6);			//该Vector对象含有6个元素

下面解释了这个Vector变量的构成:
C++语言导学 第二章 用户自定义类型 - 2.3 类

本质上,Vector对象是一个“句柄”,它包含指向元素的指针(elem)以及元素数目(sz)。在不同Vector对象中元素数目可能不同,即使同一个Vector对象在不同时刻也可能含不同数目的元素,但Vector对象本身的大小永远保持不变。这是C++语言处理可变数量信息的一项基本技术:一个固定大小的句柄指向位于“别处”(如通过new分配的*空间)的一组可变数量的数据。

在这里,我们只能通过Vector的接口访问其数据表示(成员elem和sz),而接口是由其public成员提供的:Vector(),operator()和size()。这样,2.2的read_and_sum()示例可简化为:

double read_and_sum(int s)
{
	Vector v(s);		//创建一个包含s个元素的向量
	for(int i = 0; i != v.size(); ++i)
		cin>>v[i];		//读入元素

	double sum = 0;
	for(int i = 0; i != v.size(); ++i)
		sum+=v[i];	//计算元素的和
	return sum;
}

与所属类同名的成员“函数”称为构造函数(constructor),即,它是用来构造类的对象的。因此构造函数Vector()替换了Vector_init()。与普通函数不同,编译器会保证在初始化类对象时使用构造函数,因此,定义构造函数可以消除类变量未初始化问题。

Vector(int)规定了Vector对象的构造方式。特别是,它声明需要一个整数来构造对象,这个整数用于指定元素数目。构造函数使用成员初始化列表来初始化Vector的成员:

:elem{new double[s]},sz{s}

这条语句的含义是:首先从*空间获取s个double类型的元素,然后用指向这些元素的指针初始化elem; 然后使用s初始化sz。

访问元素的功能由下标函数operator[]提供的,它返回所需元素的引用(double&,即允许读也允许写)。

size()函数的作用是向使用者提供元素数目。

显然,我们完全没有涉及错误处理,但将在3.5节提及。类似地,我们也没有提供一种机制来“归还”通过new获取的double数组,4.2.2节将介绍如何使用析构函数来优雅地完成这一任务。

struct和class没有本质区别,struct就是一种成员默认为public的class。例如,你也可以为struct定义构造函数和其他成员函数。

上一篇:vue —— Diff算法


下一篇:vue 怎么向 计算属性 computed 传递参数