类的简介
在介绍类之前,我们先来看一组对类的定义
class DATA
{
int year;
int month;
int day;
};
类的关键词是:class
在c++中,我们使用“类”来描述“对象”,对象是指现实世界中的一切事物,那么类就可以看做是对现实事物的抽象。
对于这个类而言,我们使用类定义了一个日期类。而日期就属于现实中的一个对象。
类中的成员变量,year,month,day,则是描述这个对象的具体属性,对于日期这个对象来说,他的属性就是年月日。
类属于一种数据类型,一般来说,类具有两个内容,一种是该类的属性,另一部分就是其具有的方法。
我们可以定义一个“人”类,这个类的具体属性就是,身高,体重,年龄,出生日期等等……而人所具有的睡觉,走路,上课等等……则是其所对应的方法和行为,我们对于可以抽象描述现实中事物的一种类型,就称作为类。
类的定义
class 类名
{
public:
//公共的行为或者属性
private:
//私有的行为或者属性
};
1.类名需要遵循一般的命名规则。
2.public意为公开的行为或属性,外部可以随意访问与调用。而pravite意为该部分是私有的,只供类内部进行访问与调用,外部无法使用。
3.与struct一样,结尾不可省去分号。
下面举例说明类的用法
class student
{
public:
void setmess(char *name, int age, char *grade, int num);
void showmess();
private:
char _name[20];
int _age;
char _grade[30];
int _num;
};
代码说明:
上述代码定义了一个名为student的类,其中它具有私有属性,name, age, class, num。分别表示学生的姓名,年龄,班级,学号。称为类的成员变量
在方法上,setmess用来设置属性,也就是student的属性,而showmess用来输出student的信息。而方法也称为类的成员函数。
类的实现
以上只是定义了类,并没有将类具体实现出来。类的实现就是将其方法完成的过程。类的实现有两种,一种是在类定义时就完成对其成员函数的定义,另一种则是在类定义的外部进行完成。
1>在类的内部完成成员函数的实现
class student
{
public:
void setmess(char *name, int age, char *grade, char num)
{
strcpy(_name, name);
_age = age;
strcpy(_grade, grade);
_num = num;
}
void showmess()
{
cout << "name :" << _name << endl;
cout << "age :" << _age << endl;
cout << "grade :" << _grade << endl;
cout << "num :" << _num << endl;
}
private:
char _name[20];
int _age;
char _grade[30];
int _num;
};
特别的是,如果在类体中定义的成员函数中不包括循环等控制结构,C++系统会自动将它们作为内置(inline)函数来处理。
2>在类外完成成员函数的实现
class student
{
public:
void setmess(char *name, int age, char *grade, char num);
void showmess();
private:
char _name[20];
int _age;
char _grade[30];
int _num;
};
void student::setmess(char *name, int age, char *grade, char num)
{
strcpy(_name, name);
_age = age;
strcpy(_grade, grade);
_num = num;
}
void student::showmess()
{
cout << "name :" << _name << endl;
cout << "age :" << _age << endl;
cout << "grade :" << _grade << endl;
cout << "num :" << _num << endl;
}
在类外完成成员函数的实现需要注意的是,需要使用作用域操作符“::”来对成员函数进行指引到对应的类中。而函数的类型需要在作用域操作符之前声明。
类的使用
在创建完类之后,就可以定义类的对象了,创建一个类的对象,称为对类的实例化。
#include<iostream>
#include"student.h"
using namespace std;
void main()
{
student stu1;//用定义好的类创建一个名为stu1的对象
stu1.setmess("Li Ming", 18, "class 2 grade 3", 0302006);//设置sut1的信息
stu1.showmess();//展示stu1的信息
student stu2;//用定义好的类创建一个名为stu2的对象
stu2.setmess("Mei Mei", 17, "class 2 grade 3", 0302013);//设置sut2的信息
stu2.showmess();//展示stu2的信息
}
上述代码中,创建了两个student的对象stu1和stu2,他们各自拥有不同的属性,但是公用同一个类中的方法。
在将类进行实例化之后,系统就会对该对象实际所需的空间进行分配,此时就可以使用该对象来访问或调用该对象所提供的方法和属性了。
类的构造函数与析构函数
构造函数:在创建对象的时候用来初始化对象的
- 通常来说,如果在定义类的时候未定义构造函数,那么编译器会自动产生一个默认构造函数,该构造函数的内容为空,但是它一定存在。
- 如果定义了构造函数,那么在创建对象时,就需要将构造函数所需参数传入进去。
- 构造函数的名称与类名相同,不需要指定类型。
- 构造函数可以重载,可以定义多个重载构造函数,根据实际选择需要的构造函数。
- 如果定义了构造函数,那么系统不会生成默认构造函数,创建对象时需要使用已经定义的构造函数,否则会出错。
class DATA
{
public:
DATA()
{
cout << "这个构造函数不做任何事情" << endl;
}
DATA(int year, int month, int day)
{
cout << "这个构造函数可以用来给对象添加属性" << endl;
_year = year;
_month = month;
_day = day;
}
void setdata(int year, int month, int day);
void show();
private:
int _year;
int _month;
int _day;
};
void DATA::setdata(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void DATA::show()
{
cout << "year :" << _year << endl;
cout << "month :" << _month << endl;
cout << "day :" << _day << endl;
}
在实例化这个类时,有两种方法可以设置对象的属性。
1>使用不带参的构造函数
void main()
{
DATA data;
data.setdata(2017,10,28);
data.show();
}
表示使用不带参数的构造函数,或者有默认参数值的构造函数。
该调用输出结果为
需要注意的一点是,如果定义对象时,对象后面使用了括号
如 DATA data();,并不是意为使用不带参的构造函数,而是意为声明一个返回值为DATA的函数。
2>使用带参的构造函数
void main()
{
DATA data(2017, 10, 28);
data.show();
}
表示调用参数为三个int型的构造函数
该调用输出结果为
析构函数:在对象声明周期结束时,释放对象创建过程中所占用的外部资源。
- 如果未定义析构函数,那么系统同默认构造函数一样,会自动生成一个默认析构函数。
- 析构函数无法重载,只会存在一个。
析构函数定义如下:
~DATA(){}
与构造函数一样,都使用类名作为函数名,无类型。但是析构函数名前会多一个~符号。
一般来说,如果对象创建过程中使用new申请了一个空间,那么释放时都在析构函数中使用delete进行释放。
析构函数的调用与构造函数调用的顺序相反。
c++中class与c语言中struct的不同之处
在c语言中,我们通常使用struct来定义一组成员变量,而不能定义一个成员函数。
在c++中,引入了class的概念,它的作用和struct一样,但是他可以定义成员函数。这就使得c++可以面向对象编程。
因为c语言中的struct只是一种特殊的数据类型,它面向的是过程。而class是对实体的一种抽象数据类型,它面向的是对象。
在定义时,如果未声明成员的访问限定符,那么class中默认为private,在struct中默认为public。
在计算class与struct的大小上,两者都相同,使用成员变量中最大变量所占空间字节数进行对齐。
因此,在c语言中,struct的大小为0字节,因为结构体中没有任何数据类型。
但是在c++中,空类与空结构体的大小都为1字节,在c++标准中有这样一段话“no object shall have the same address in memory as any other variable” ,即任何不同的对象不能拥有相同的内存地址,因此,如果空类大小为0字节,对象会存在同一个地址上,导致无法区分各对象。
将空类的大小设置为1字节,即可将各个对象区分开来,以确保各个对象拥有不同的地址。