
目录
一、类的定义
1.1类定义的格式
C++中类的定义和C语言中结构体类型的定义非常相似,我们先来看C语言中结构体类型的定义,进而延申到C++中类的定义。
C语言中结构体类型的定义:
cpp
struct book
{
char book_name[100];
char book_suthor[20];
float book_price;
char id[20];
};
C++中类的定义,需要用到class关键字,然后后面加类名,紧接着{}中为类的主题,{}后面紧跟着分号,类的定义如下(以日期类为例):
cpp
class Data
{
public:
void Init(int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << '/' << endl;
}
private:
int _year;
int _month;
int _day;
};
我们对比C语言中结构体类型的定义和C++中类的定义,可以发现两者存在如下区别:
1.结构体类型中只有成员变量(成员属性),而类类型中除了成员变量(成员属性)外,还多了一种成员------成员函数,如上述日期类中的Init函数。
2.类类型中还存在访问限定符(如上述日期类中的public、private)来限定类类型中成员的访问权限。
在C++中struct也可以用来定义类,如下代码所示:
cpp
struct book
{
public:
void Init()
{
}
private:
char book_name[100];
char book_suthor[20];
float book_price;
char id[20];
};
C++中struct定义的类和class定义的类,两者的区别在于:struct定义的类成员的默认访问权限为共有访问(public),class定义的类成员的默认访问权限为私有访问(private)。
1.2访问限定符
在上述类的定义中,我们已经提到了public和private两种访问限定符,访问限定符有以下三类,分别为共有、私有和保护:
访问限定符的作用是限制类外成员对类中成员的访问权限。
二、实例化
2.1实例化的概念
我们用类类型创建对象的过程,称为实例化。如下代码:
cpp
#include<iostream>
using namespace std;
class Data
{
public:
void Init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void Print()
{
cout << _year << '/' << _month << '/' << _day << '/' << endl;
}
private:
int _year;
int _month;
int _day;
};
int main()
{
Data d1;
Data d2;
Data d3;
d1.Init(2024, 1, 20);
d2.Init(2024, 1, 21);
d3.Init(2024, 1, 22);
return 0;
}
main函数中的d1、d2、d3便是Data类所创建(实例化)的对象。
2.2对象大小的计算
在计算对象大小之前,我们需要知道:在C++中通过类可以创建多个对象,而每个对象各自有相互独立的成员变量,但是成员函数用的是同一个,而成员函数放在一个公共区域内供多个对象进行调用,所以我们在计算对象的大小时,只需计算对象中成员变量的大小。
对象大小的计算和结构体大小的计算方法是一致的,都要用到内存对齐规则。内存对齐规则如下:

除此之外,在对象的计算中,有一种特殊的类需要我们注意,该类称为空类,空类的特点是没有成员变量,如下代码所示:
cpp
class A
{
public:
void Print()
{
//...
}
};
class B
{};
空类没有成员变量可以计算大小,但是空类统一占据1个字节,原因在于空类也要用来定义对象,若空类大小是0个字节,就无法定义对象开辟空间,所以这里1个字节的作用纯粹是为了占位标识对象存在。
三、this指针
3.1this指针的使用
在上述的Data类中有两个成员函数Init和Print,成员函数体内没有关于不同对象的区分,但是d1、d2在调用成员函数时,成员函数是如何准确的访问到d1和d2呢?this指针便用来解决这里的问题。
this指针默认的存在于每一个成员函数形参部分的第一个位置。比如Data类中的Init的真实原型为
cpp
void Init(Data* const this,int year,int month,int day);
成员函数中访问成员变量,本质都是通过this指针进行访问的,如下代码所示:
cpp
class Data
{
public:
void Init(int year, int month, int day)
{
this->_year = year;
this->_month = month;
this->_day = day;
}
void Print()
{
cout << this->_year << '/' <<this-> _month << '/' <<this-> _day << '/' << endl;
}
private:
int _year;
int _month;
int _day;
};
需注意,this指针不能再形参和实参的位置显示的写(编译时编译器会处理),但是可以在函数体内显示的使用this指针。
3.2有关this指针的样例
样例1:
样例2:
样例3:

四、C++和C语言实现Stack的对比
面向对象有三大特性:封装、继承、多态。而C++中的类便体现出封装这一特性,这一特性可以通过C和C++中实现Stack的差异中体现出来:
C语言实现:
cpp
#include<stdio.h>
#include<stdlib.h>
#include<stdbool.h>
#include<assert.h>
typedefintSTDataType;
typedefstructStack
{
STDataType*a;
inttop;
intcapacity;
}ST;
voidSTInit(ST*ps)
{
assert(ps);
ps->a=NULL;
ps->top=0;
ps->capacity=0;
}
voidSTDestroy(ST*ps)
{
assert(ps);
free(ps->a);
ps->a=NULL;
ps->top=ps->capacity=0;
}
voidSTPush(ST*ps,STDataTypex)
{
assert(ps);
//满了,扩容
if(ps->top==ps->capacity)
{
intnewcapacity=ps->capacity==0?4:ps->capacity*2;
STDataType*tmp=(STDataType*)realloc(ps->a,newcapacity*
sizeof(STDataType));
if(tmp==NULL)
{
perror("reallocfail");
return;
}
ps->a=tmp;
ps->capacity=newcapacity;
}
ps->a[ps->top]=x;
ps->top++;
}
boolSTEmpty(ST*ps)
{
assert(ps);
returnps->top==0;
}
voidSTPop(ST*ps)
{
assert(ps);
assert(!STEmpty(ps));
ps->top--;
}
STDataTypeSTTop(ST*ps)
{
assert(ps);
assert(!STEmpty(ps));
returnps->a[ps->top-1];
}
intSTSize(ST*ps)
{
assert(ps);
returnps->top;
}
intmain()
{
STs;
STInit(&s);
STPush(&s,1);
STPush(&s,2);
STPush(&s,3);
STPush(&s,4);
while(!STEmpty(&s))
{
printf("%d\n",STTop(&s));
STPop(&s);
}
STDestroy(&s);
return0;
}
C++实现:
cpp
#include<iostream>
usingnamespacestd;
typedefintSTDataType;
classStack
{
public:
//成员函数
voidInit(intn=4)
{
_a=(STDataType*)malloc(sizeof(STDataType)*n);
if(nullptr==_a)
{
perror("malloc申请空间失败");
return;
}
_capacity=n;
_top=0;
}
voidPush(STDataTypex)
{
if(_top==_capacity)
{
intnewcapacity=_capacity*2;
STDataType*tmp=(STDataType*)realloc(_a,newcapacity*
sizeof(STDataType));
if(tmp==NULL)
{
perror("reallocfail");
return;
}
_a=tmp;
_capacity=newcapacity;
}
_a[_top++]=x;
}
voidPop()
{
assert(_top>0);
--_top;
}
boolEmpty()
{
return_top==0;
}
intTop()
{
assert(_top>0);
return_a[_top-1];
}
voidDestroy()
{
free(_a);
_a=nullptr;
_top=_capacity=0;
}
private:
//成员变量
STDataType*_a;
size_t_capacity;
size_t_top;
};
intmain()
{
Stacks;
s.Init();
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
while(!s.Empty())
{
printf("%d\n",s.Top());
s.Pop();
}
s.Destroy();
return0;
}
