参考Primer C++ 第七章第一节
类的基本思想是数据抽象和封装。数据抽象是一种依赖于接口和实现分离的编程及设计技术。类的接口包括用户所能执行
的操作;类的实现包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。
1.定义抽象数据类型
1.1设计类
确定变量、成员函数、非成员函数
1.2定义类
Sales_data类如下所示:
struct Sales_data {
//新成员:关于Sales_data对象的操作
std::string isbn() const {return bookNo;}
Sales_data& combine(const Sales_data&);
double avg_price() cosnt;
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
//Sales_data的非成员接口函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);
定义在类内部的函数是隐式的inline函数。
任何对类成员的直接访问都被看做this的隐式引用。this的类型是指向类类型非常量版本的常量指针。
我们在类的外部定义成员函数时,成员函数的定义必须与它的声明匹配。也就是说,返回类型、参数列表和函数名都必须与类
内部的声明保持一致。
定义一个返回this对象的函数
Sales_data& Sales_data::combine(cosnt Sales_data &rhs)
{
units_sold += rhs.units_sold; //把rhs的成员加到this对象的成员上
revenue += rhs.revenue;
return *this; //返回调用该函数的对象
}
1.3定义类相关的非成员函数
一般来说,如果非成员函数是类接口的组成部分,则这些函数的声明应该与类在同一个头文件里。
1.4 构造函数
类通过一个或者几个特殊的成员函数来控制其对象的初始化过程,这些函数成为构造函数。
构造函数的任务是初始化类对象的数据成员。类可以包含多个构造函数,不同的构造函数之间必须在参数数量或者参数类型
上有所区别。
**合成构造函数**
类通过一个特殊的构造函数来控制默认初始化过程,则该函数为默认构造函数。默认构造函数无须任何实参。
**定义Sales_data的构造函数**
struct Sales_data {
Sales_data() = defult;
Sales_data(const std::string &s) :bookNo(s) {}
Sales_data(const std::string &s,unsigned n,double p):
bookNo(s),units_sold(n),revenue(p*n) {}
Sales_data(std::istream &s);
std::string isbn() const {return bookNo;}
Sales_data& combine(const Sales_data&);
double avg_price() const;
std::string bookNo;
unsigned units_sold =0;
double revenue =0;
};
在C++11新标准中,Sales_data() = default ;其作用完全等价于合成默认构造函数。
构造函数 Sales_data(const std::string &s) :bookNo(s) {} 和 构造函数 Sales_data(const
std::string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n) {} 中的bookNo(s)和bookNo(s),units_sold(n),revenue(p*n)为构造函数初值列表,负责为新创建的对象的一个或者几个数据成员赋初值。
**在类的外部定义构造函数**
以istream为参数的构造函数需要执行一些实际的操作,比如:调用read函数以给数据成员赋初值:
Sales_data::Sales_data(std::istream &is)
{
read(is, *this); //read函数的作用是从is中读取一条交易信息,然后存入到this对象中
}
1.5 拷贝、赋值和析构
略