文章目录
前言
本文将讲述c++类和对象的初步认识,包括“类的访问限定符及封装”“类的作用域""类的实例化”“类的对象大小的计算”“类成员函数的this指针”等等。
持续更新中~
1.面向过程和面向对象初步认识
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完
成。
2.类的引入
3.类的定义
那么类是怎么定义的呢?
和C语言的结构体非常相似,是这样的
4.类的访问限定符及封装
4.1 访问限定符
4.2 封装
5.类的作用域
6.类的实例化
什么是类的实例化?
这是什么意思?
7.类的对象大小的计算
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
char _a;
};
试着推导一下
假设一
假设二
假设三
假设有了,现在我们来验证一下
// 类中既有成员变量,又有成员函数
class A1 {
public:
void f1(){}
private:
int _a;
};
// 类中仅有成员函数
class A2 {
public:
void f2() {}
};
// 类中什么都没有---空类
class A3
{};
对上面代码,我们分别使用sizeof计算一下它的大小,
但是在此之前,我们先试着推导一下,类之前就是结构体的升级版嘛
所以按照结构体内存对齐规则计算一下,
这里我们简单复习一下它是什么
按照这样说的话,函数一般是以地址的形式存储的,也就是4字节,我们先猜它是这样。
那么A1就是8,A2就是4,A3就是0
验证一下
哦豁,怎么和我们猜的不一样?我们把A1、A2的函数去掉看一下
不变
现在就可以总结一下了,
- 类中既有成员变量,又有成员函数,它的实际大小就是成员变量之和,当然也要注意内存对齐
- 类中仅有成员函数或者类中什么都没有(空类),会比较特殊,编译器给了空类一个字节来唯一标识这个类的对象
懂了吧
8.类成员函数的this指针
8.1 this指针的引出
8.2 this指针的特性
8.3. C语言和C++实现Stack的对比
1. C语言实现
typedef int DataType;
typedef struct Stack
{
DataType* array;
int capacity;
int size;
}Stack;
void StackInit(Stack* ps)
{
assert(ps);
ps->array = (DataType*)malloc(sizeof(DataType) * 3);
if (NULL == ps->array)
{
assert(0);
return;
}
ps->capacity = 3;
ps->size = 0;
}
void StackDestroy(Stack* ps)
{
assert(ps);
if (ps->array)
{
free(ps->array);
ps->array = NULL;
ps->capacity = 0;
ps->size = 0;
}
}
void CheckCapacity(Stack* ps)
{
if (ps->size == ps->capacity)
{
int newcapacity = ps->capacity * 2;
DataType* temp = (DataType*)realloc(ps->array,
newcapacity*sizeof(DataType));
if (temp == NULL)
{
perror("realloc申请空间失败!!!");
return;
}
ps->array = temp;
ps->capacity = newcapacity;
}
}
void StackPush(Stack* ps, DataType data)
{
assert(ps);
CheckCapacity(ps);
ps->array[ps->size] = data;
ps->size++;
}
int StackEmpty(Stack* ps)
{
assert(ps);
return 0 == ps->size;
}
void StackPop(Stack* ps)
{
if (StackEmpty(ps))
return;
ps->size--;
}
DataType StackTop(Stack* ps)
{
assert(!StackEmpty(ps));
return ps->array[ps->size - 1];
}
int StackSize(Stack* ps)
{
assert(ps);
return ps->size;
}
int main()
{
Stack s;
StackInit(&s);
StackPush(&s, 1);
StackPush(&s, 2);
StackPush(&s, 3);
StackPush(&s, 4);
printf("%d\n", StackTop(&s));
printf("%d\n", StackSize(&s));
StackPop(&s);
StackPop(&s);
printf("%d\n", StackTop(&s));
printf("%d\n", StackSize(&s));
StackDestroy(&s);
return 0;
}
总结:
- 每个函数的第一个参数都是Stack*
- 函数中必须要对第一个参数检测,因为该参数可能会为NULL
- 函数中都是通过Stack*参数操作栈的
- 调用时必须传递Stack结构体变量的地址
结构体中只能定义存放数据的结构,操作数据的方法不能放在结构体中,即数据和操作数据
的方式是分离开的,而且实现上相当复杂一点,涉及到大量指针操作,稍不注意可能就会出
错。
2. C++实现
typedef int DataType;
class Stack
{
public:
void Init()
{
_array = (DataType*)malloc(sizeof(DataType) * 3);
if (NULL == _array)
{
perror("malloc申请空间失败!!!");
return;
}
_capacity = 3;
_size = 0;
}
void Push(DataType data)
{
CheckCapacity();
_array[_size] = data;
_size++;
}
void Pop()
{
if (Empty())
return;
_size--;
}
DataType Top(){ return _array[_size - 1];}
int Empty() { return 0 == _size;}
int Size(){ return _size;}
void Destroy()
{
if (_array)
{
free(_array);
_array = NULL;
_capacity = 0;
_size = 0;
}
}
private:
void CheckCapacity()
{
if (_size == _capacity)
{
int newcapacity = _capacity * 2;
DataType* temp = (DataType*)realloc(_array, newcapacity *
sizeof(DataType));
if (temp == NULL)
{
perror("realloc申请空间失败!!!");
return;
}
_array = temp;
_capacity = newcapacity;
}
}
private:
DataType* _array;
int _capacity;
int _size;
};
int main()
{
Stack s;
s.Init();
s.Push(1);
s.Push(2);
s.Push(3);
s.Push(4);
printf("%d\n", s.Top());
printf("%d\n", s.Size());
s.Pop();
s.Pop();
printf("%d\n", s.Top());
printf("%d\n", s.Size());
s.Destroy();
return 0;
}
总结:
respect !
下篇见!