PoEdu培训 C++班 第四课 类和对象(2)
文章类别: 培训笔记 0 评论

PoEdu培训 C++班 第四课 类和对象(2)

文章类别: 培训笔记 0 评论

类和对象(2)

由作业引发的问题

一定要注意不要内存泄露.
当前程序在结束的时候, 会将所有使用过的内存释放掉.
内存泄露是程序员必须解决的问题, 不可依托于操作系统

实现一个Array类, 可变长

#include <iostream>

using namespace std;


class HadesArray
{
private:
    int* _iData;
    size_t _iLen;
    size_t _index;

public:
    HadesArray(std::size_t iLen = 5)
    {
        _iLen = iLen;
        _index = 0;
        _iData = new int[_iLen];
    }

    ~HadesArray()
    {
        if (_iData)
            delete[] _iData;
    }

    // 后边课程会使用运算符的重载
    int GetData(const std::size_t index) const
    {
        if (index < _iLen)
            return _iData[index];
        return 0;
    }

    // 后边课程会使用运算符的重载
    void SetData(const std::size_t index, const int iData)
    {
        if (index < _iLen)
            _iData[index] = iData;
    }

    size_t GetLen() const
    {
        return _index;
    }

    void AddData(const int iData)
    {
        if (_index >= _iLen)
        {
            _iLen = _index * 2;
            // 每次分配2倍INDEX的空间
            // 5 * 2 * 2 * 2 效率最高~
            int* tmp = new int[_iLen];
            memset(tmp, 0x00, sizeof(tmp));
            memcpy(tmp, _iData, _index * sizeof(int));
            delete[] _iData;
            _iData = tmp;
        }
        _iData[_index++] = iData;
    }

    void AddData(const HadesArray& data)
    {
        for (size_t i = 0; i < data._index; ++i)
        {
            // 在这里 可以使用private的_index
            // 因为是在同一个类中
            AddData(data.GetData(i));
        }
    }

    void AddData(const int* data, size_t len)
    {
        for (size_t i = 0; i < len; ++i)
        {
            AddData(data[i]);
        }
    }

    void PrintData(const size_t len = 0) const
    {
        for (size_t i = 0; i < (len == 0 ? _index : len); ++i)
        {
            cout << _iData[i] << " ";
            if ((i % 6 == 0) && (i != 0))
                cout << endl;
        }
        cout << endl;
    }
};




int main(int argc, char* argv[])
{
    HadesArray arrayTest;

    arrayTest.AddData(1);
    arrayTest.AddData(2);
    arrayTest.AddData(3);
    arrayTest.AddData(4);
    arrayTest.AddData(5);
    arrayTest.AddData(6);
    arrayTest.AddData(7);
    arrayTest.AddData(8);
    arrayTest.AddData(9);
    arrayTest.AddData(10);
    arrayTest.AddData(11);
    arrayTest.AddData(12);
    arrayTest.AddData(13);
    arrayTest.AddData(14);
    arrayTest.AddData(15);

    HadesArray arrayAdd;
    arrayAdd.AddData(16);
    arrayAdd.AddData(17);
    arrayAdd.AddData(18);
    arrayAdd.AddData(19);
    arrayAdd.AddData(20);
    arrayAdd.AddData(21);

    arrayTest.AddData(arrayAdd);

    int iVals[20] = { 0 };
    for (size_t i = 0; i < 20; ++i)
    {
        iVals[i] = 666;
    }

    arrayTest.AddData(iVals, 20);

    arrayTest.PrintData();

    return 0;
}

this指针

this指针是每一个对象中的隐藏属性.
每一个对象都会有一个this指针.
它的主要作用就是用来区分不同的对象.
this本质上就是一个对象的代名词.

const方法

在方法的最后边 加上 const 关键字的方法, 我们称之为 const方法.
const方法不被允许对我们当前对象产生任何的修改
const方法能够访问类的const成员, 而其他非const方法不能访问类的const成员.
const方法能够被const对象进行调用.
const对象只能调用const方法.
const方法只能调用const方法.

错误的例子

const方法重要的还是它的语义
// 一个本不应该出现的例子
#include <iostream>

using namespace std;


class HadesArray
{
private:
    int* _iData;
    size_t _iLen;
    size_t _index;

public:
    HadesArray(std::size_t iLen = 5)
    {
        _iLen = iLen;
        _index = 0;
        _iData = new int[_iLen];
    }

    ~HadesArray()
    {
        if (_iData)
            delete[] _iData;
    }

    void SetData(const std::size_t index, const int iData) const
    {
        if (index < _iLen)
            _iData[index] = iData;
    }

    void AddData(const HadesArray& data)
    {
        cout << "================================" << endl;
        data.PrintData();
        data.SetData(0, 9);
        data.PrintData();
        cout << "================================" << endl;
    }

    void PrintData(const size_t len = 0) const
    {
        for (size_t i = 0; i < (len == 0 ? _index : len); ++i)
        {
            cout << _iData[i] << " ";
            if ((i % 6 == 0) && (i != 0))
                cout << endl;
        }
        cout << endl;
    }

};


int main(int argc, char* argv[])
{
    HadesArray arrayTest;

    arrayTest.AddData(1);

    HadesArray arrayAdd;
    arrayAdd.AddData(16);
    arrayAdd.AddData(17);
    arrayAdd.AddData(18);
    arrayAdd.AddData(19);
    arrayAdd.AddData(20);
    arrayAdd.AddData(21);

    cout << "=================" << endl;
    arrayAdd.PrintData();
    cout << "=================" << endl;
    arrayTest.AddData(arrayAdd);
    cout << "-----------------" << endl;
    arrayAdd.PrintData();
    cout << "-----------------" << endl;

    return 0;
}
输出结果:
=================
16 17 18 19 20 21
=================
================================
16 17 18 19 20 21
9 17 18 19 20 21
================================
-----------------
9 17 18 19 20 21
-----------------

const方法 还是 可以修改 对象的值
但是, 这个例子本身就不应该存在.
它完全破坏了const的语义.

切记不可写这样的代码.

小知识

下节预告


未完待续

如有错误,请提出指正!谢谢.

回复