C语言是一门面向过程的编程语言,主要关注的是过程,分析解决问题的步骤,利用函数一步一步解决问题。
C++是一门面向对象的编程语言,更加关注的是对象,将一个问题拆解成几个对象,通过对象之间的联系等来解决问题。C++面向对象的特征体现在封装,继承,多态,抽象,反射等。
话不多说,开始正题。
C语言中,结构体只能定义变量。C++更注重面向对象,引入了类这个数据结构,不仅可以定义变量,还能定义函数。
一.类的定义
类是具有相同或相似性质的对象的抽象。类是对象的抽象,对象是类的具体。(这句话有点抽象,其实说白了类就是相似对象的模板)。对象就是通过类这一类型定义的变量。
类的模板是
class 类名//类名一般第一个字母大写
{
//默认是私有权限
public:
成员,数据,函数
private:
成员,数据,函数
protected:
成员,数据,函数
};//定义域加分号
对于类的特别说明:
1.类的定义的最后有一个分号,不能省略,原因是类的定义是声明一个数据结构,而不是定义一个函数,定义后面要有分号结束。
2.类成员(成员变量和成员函数)访问权限的关键词 private 私有 (默认),protected 保护,public 共有三种,可以按任意顺序,任意出现多次,一个成员只能有一种访问权限。
3.不能在类内给数据成员赋初值,只有给对象数据成员赋初值。
4.成员函数两种方式(1)在类里声明,类外定义。(2)在类里声明,在类里定义。成员函数可以重载。
5.C语言中struct是用来定义结构体的。C++中,兼容C的struct定义结构体的用法,但是同时struct也可用来定义类。.C++中的class 和struct 区别:class类默认私有,struct类 默认共有。
6.如何计算一个类实例化出的对象大小,计算成员变量之和,而且考虑内存对齐规则。没有成员变量的对象内存是1。开一个字节的空间,不是为了存数据,而是为了占位,表明对象存在。
注意:
对象中只存储成员变量,不存储成员函数。
原因一个类能实例出N个对象,每个对象的成员变量都可以储存不同的值,但是调用的函数确是同一个。如果每个对象都放成员函数,而这些成员函数是一样的,浪费空间。成员函数在代码区。
下图可以体现
class A
{
public:
void Print()
{
cout<<a<<endl;
}
void Show()
{
cout<<"Show()"<<endl;
}
private:
int a;
};
int main()
{
A* p=NULL;
p->Print();//此行代码,编译不通过
p->Show();//此行代码,编译通过
return 0;
}
成员函数存在公共的代码段,所以p->Show()不会去p指向的对象上找,访问成员函数,才回去找。
二.类的默认成员函数
在C++里有6个默认成员函数
1.构造函数 在对象构造时调用的函数,这个函数完成初始化工作,在建立对象后面使用:
对象(参数)
class Date
{
public:
//构造函数
Date(int year,int month)
{
_year=year;
_month=month;
}
private:
int _year;
int _month;
};
int main()
{
Date D1(2023,5);//对象(参数)
return 0;
}
特点:1.构造函数名与类名相同
2.没有返回值,没有返回类型不是void
3.对象实例化时编译器自动调用对应的构造函数
4.构造函数可以重载。(见下代码)
class Date
{
public:
//构造函数
Date(int year,int month)
{
_year=year;
_month=month;
}
Date()
{
_year=0;
_month=0;
}
private:
int _year;
int _month;
};
int main()
{
Date D1(2023,5);//对象(参数)
Date D2;//不能加括号()
return 0;
}
5.如果类定义中没有显示定义构造函数,则C++编译器会自动生成一个无参的默认构造函数(共有属性),一旦用户显式定义构造函数编译器将不再生成。若要调用显式构造函数则在创建新对象时传相应的参数。(见上代码)
默认生成的无参的构造函数和析构函数(语法坑:双标狗)
(1)针对内置类型的成员变量没有做处理
(2)针对自定义类型的成员变量(例如:类里的类),调用成员变量的构造函数初始化或者析构函数清理。
更好的方式:全缺省(想传几个,传几个)见下代码
class Date
{
public:
Date(int year=0,int month=1)//全缺省
{
_year=year;
_month=month;
}
private:
int _year;
int _month;
};
默认构造函数(都不用传参数):
1.自己实现的无参的构造函数。
2.全缺省的构造函数
3.我们不写,编译器自己生成的构造函数。
注意:默认构造函数只能有一个!!!
二.析构函数
析构函数:与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。
1.在类名前加~(取反符号)。
2.无参数,无返回值。
3.一个类有且只有一个析构函数。若未显示定义,系统会自动生成默认的析构函数。
4.在对象生命周期到了之后,自动调用。完成对象里面的资源清理工作(动态内存),而不是销毁工作。
5.后创建的先析构