类的概念
类的基本思想是数据抽象和封装。数据抽象是一种把接口和实现分离的编程技术。类的接口包括用户所能够执行的操作,类的实现包括类的数据成员、负责接口实现的函数体和各种私有函数。
封装实现了类的接口和实现的分离。封装隐藏了类的实现,封装过后,用户只能访问类的接口,而不能访问类的实现。
类是一种将抽象转换为用户定义类型的C++工具,它将数据表示和操纵数据的方法组合成一个整体。例如一个日常生活时间类,时间对象有两个属性,小时和分钟,根据需要应该能够对每个日常事务所花的时间进行操作和显示。操作和显示就需要类的接口函数。
一般的类由两部分组成:
- 类声明:以数据成员的方式描述数据部分,以成员函数(被称为方法)的方式描述接口函数。
- 类方法定义:描述如何实现类成员函数。
简单地说,类声明给出了类的框架,而方法定义给出了类的细节。
私有成员和公有成员
类中有两个关键字private和public,它们描述了程序对类的成员的访问控制。由于隐藏数据是面向对象编程的主要目的之一,所以数据成员一般放在private部分,而接口函数则放在public部分。
#include <iostream>
using namespace std;
class Time{
private:
int day;
int month;
int get_numbers;
public:
Time(); //默认构造函数
Time(int h, int m = 0); //显式构造函数
Time(const Time &); //拷贝构造函数
~Time(); //析构函数
//------展示函数show() //在const函数中不可调用非const函数成员
void Time::show() const
{
cout << "month:" << month<< " " << "day:" << day<< " "<<endl;
}
};
如上面代码所示:Time为一个类,其中 day,month和 get_numbers为Time 的私有成员,而Time()等为公有成员。公有成员等可以直接访问得到,但是私有成员只能通过公有成员才能间接访问到。
Time today(1,15);
today.show(); //合法
cout<<today.day<<endl;//非法
注: 类的成员默认是私有的,而结构体成员则默认是公有的
成员函数定义的时候,也可以将函数的实现写进类声明的头文件中,但是一定要添加inline关键字。如果不让函数成为内联函数,当头文件被多个源文件引用时,会出现重定义。(inline函数是需要编译器在遇到它的地方根据它的定义把它内联展开的,而并非是普通函数那样可以先声明再链接的,内联函数并不会参与链接,所以编译器就需要在编译时看到内联函数的完整定义才行。C++规定,内联函数可以在程序中定义多次,只要内联函数的定义在一个.cpp文件中只出现一次,并且在所有的.cpp文件中,这个内联函数的定义是一样的,就能通过编译。)
类的const成员
为了保证数据的安全,在类的成员函数不需要对对象的值进行修改的时候,应该尽量将成员函数定义为const成员函数。定义一个const类对象与定义一个const普通对象一样,需要在对象前加上const 关键字。
定义一个的const成员函数时const关键字是放在括号后面的,他的意思是这个函数不不能修改调用它的对象的值。与返回值是否是常量无关。
void Time::show() const
{
cout << "month:" << month<< " " << "day:" << day<< " "<<endl;
}
一个const对象是无法调用非const成员函数的,以免非const成员函数修改const对象的数据,这无疑降低了程序出错的可能性,而非const对象是可以调用const成员函数的。以下面的代码为例。
Time swiming(0, 45); //非const对象
const Time study(8, 5); //const对象只能调用const成员函数。
study.reset(0,0); //非法,const对象无法调用非const成员函数。
study.show(); //合法,show()是const成员函数。
swiming.show(); //合法;
当然了,在const函数中修改对象的值是非法的,编译器无法通过。
成员初始化规则
const修饰的变量定义后就不能更改了,因此,需要使用初始化列表来初始化。
引用在进行初始化后就不会再改变,因此,也需要使用初始化列表来初始化。
数据成员是对象时候,需要调用构造函数进行初始化(继承时调用基类构造函数)
static与类有关,不需要使用初始化列表。