前言

本文将讲述c++类和对象的初步认识,包括“类的访问限定符及封装”“类的作用域""类的实例化”“类的对象大小的计算”“类成员函数的this指针”等等。

持续更新中~

1.面向过程和面向对象初步认识

C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完

成。

2.类的引入

3.类的定义

那么类是怎么定义的呢?

和C语言的结构体非常相似,是这样的

4.类的访问限定符及封装

4.1 访问限定符

4.2 封装

5.类的作用域

6.类的实例化

什么是类的实例化?

这是什么意思?

C++之类和对象的初步认识-LMLPHP

C++之类和对象的初步认识-LMLPHP

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

验证一下

C++之类和对象的初步认识-LMLPHP

哦豁,怎么和我们猜的不一样?我们把A1、A2的函数去掉看一下

C++之类和对象的初步认识-LMLPHP

不变

现在就可以总结一下了,

  • 类中既有成员变量,又有成员函数,它的实际大小就是成员变量之和,当然也要注意内存对齐
  • 类中仅有成员函数或者类中什么都没有(空类),会比较特殊,编译器给了空类一个字节来唯一标识这个类的对象

懂了吧

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 !

下篇见!
C++之类和对象的初步认识-LMLPHP

04-03 11:29