C++第三课-之二(类和对象)

来源:互联网 发布:软件开发立项申请表 编辑:程序博客网 时间:2024/06/05 22:57

在使用new申请空间的时候,需要及时的delete掉,避免内存泄露。当程序结束的时候,会释放所有使用过的内存

我们用一个可变长的int类型的数组来举一个例子

#include <iostream>// MyArray 现在的数组很难用 不可变长的数组// new delete   更改长度时,需要new  copy delete三个步骤的操作// malloc free relloc   只需要一步就可以了// new 和 delete是一对,malloc和free是一对,不能混用class MyArray{public:    // 不需要传递参数的构造函数称为默认构造函数    // 这个默认构造函数是有问题的,这样会导致每次在AddData的时候,造成_len永远等于0,无法分配内存,导致程序崩溃    //MyArray()    //{    //  _len = 0;    //  _index = 0;    //  _data = nullptr;    //}    MyArray(const std::size_t len = 10)    {        // this指针的使用        _len = len; // 等价于this->_len = len,下面的都一样,需要说明的是,this指针和类是没有关系的,                    // this指针和对象是有关系的,this就是一个对象的代名词        _index = 0;        _data = new int[len];    }    MyArray(const std::size_t len, const int num)    {        //MyArray(len);     // error C2082: 形参“len”的重定义                            // 不能这样调用,因为构造还是有他的调用规则        //this->MyArray(len);   // “函数样式转换”: 位于“->”运算符右边时非法                            // 此时用this出问题,是因为对象没有出现        for (unsigned int i=0; i<len; ++i)        {            _data[i] = num;        }    }    ~MyArray()    {        if (_data)            delete[]_data;    }    int GetData(const std::size_t index) const // const方法就能被const修饰的对象所调用,但是const对象只能调用const方法    {                                           // 需要注意的是,在加const的时候,要注意语义,我们不能将AddData的方法改                                                // 成const的,因为我们明明就是要修改里面的变量的                                                // const代表的语义是值不能被修改                                                // 我们不能尝试着让别人(主要是指电脑)来解决自己的错误,还不如自己就不犯这个错误        // 但是这种访问方式也是有问题的        if (_len > index)        {            return _data[index];        }        return 0;    }    void SetData(const std::size_t index, const int num)    {        if (_len > index)        {            _data[index] = num;        }    }    // 获取数组的有效长度    std::size_t GetLength()    {        return _index;    }    void AddData(const int num)    {        // 不知道需不需要new,有可能还有剩余的空间        if (_index >= _len)        {            _len = _index * 2;            int *tmp = new int[_len];   // 每次分配_index*2的空间            memcpy(tmp, _data, _index*sizeof(int)); // 需要注意的是,memcpy是按字节拷贝的,我们应该再乘以类型的长度            delete[]_data;      // 当越界的时候,delete就会出问题,会出现异常            _data = tmp;        }        _data[_index++] = num;    }    void AddData(const MyArray &data)    {        for (unsigned int i = 0; i < data._index; ++i)        {            // 这个例子主要是想说明私有成员也是可以被访问的,但是访问的条件也是在类的内部前提下,此时就可以编译通过            // 引申说明了类的访问权限(public、private、protected)以及我们所熟知的const等等,它们都是在编译层面上做检测            AddData(data.GetData(i));   // error C2662: “int MyArray::GetData(const std::size_t)”: 不能将“this”指针从“const MyArray”转换为“MyArray &”                                        // this指针,是每一个对象里面的隐藏属性,每一个都会有一个this指针,它们是用来区分不同的对象            //data.SetData(0, 100);     // 这句话也是错误的,因为它不符合const的语义,它和上面的data.GetData(i)是一样的                                        // 所以我们也需要将我们的方法也变成一个const的方法,才能被const修饰后所调用                                        // 那么什么是const方法呢?顾名思义,不会改变方法中的变量的方法称为const方法        }    }    // 直接加一个数组    void AddData(const int *data, const std::size_t len)    {        for (unsigned int i=0; i<len; ++i)        {            AddData(data[i]);        }    }    // size_t C风格    // std::size_t C++风格    //int &Index(const std::size_t index)    //{    //  // 这里需要判断index的值是否越界    //  if (index < _len)    //  {    //      return _data[index];    //  }    //  // 这里需要抛出一个异常    //  // 如果不使用异常体系,那么就需要最原始的Get和Set函数了    //}private:    // 把数据作为私有的,这样会更安全    // 私有变量在外部是无法使用的,但是在类的内部还是可以使用的    int *_data;    std::size_t _len;   // 已经分配的空间    std::size_t _index; // 已经使用的空间};int main(){    MyArray array;    array.AddData(1);    array.AddData(2);    array.AddData(3);    array.AddData(4);    array.AddData(5);    array.AddData(6);    array.AddData(7);    array.AddData(8);    array.AddData(10);    array.AddData(11);    array.AddData(12);    array.AddData(13);    array.AddData(14);    array.AddData(15);    array.AddData(16);    array.AddData(17);    array.AddData(18);    array.AddData(19);    array.AddData(20);    array.AddData(21);    array.AddData(22);    array.AddData(23);    array.AddData(24);    array.AddData(25);    array.AddData(26);    array.AddData(27);    array.AddData(28);    array.AddData(29);    array.AddData(30);    return 0;}
1 0
原创粉丝点击