moc 发表于 2018-9-2 20:35:00

033-C++之运算符重载2

1、重载= 内存泄露场景
类中有挂了内存块的指针成员,在使用下面的=重载时,会造成内存泄露,十分隐蔽。
void operator=(name &obj)
{
        char *pn = obj.GetPn();
        //if (pname != NULL)delete[] pname;//如果没有此句,会造成内存泄漏
        pname = new char;
        if (pname != NULL)strcopy(pname, pn);
        // delete[] pn;   
        size = strlen(pn);
}
2、[]===!=   操作符的重载
使用 .h 和 .cpp 类的定义和实现 分离的方式完成上述操作符的重载,以及测试。
Array.h
#pragma once

class Array
{
private:
        int mLength;
        int* mSpace;

public:
        Array(int length);
        Array(const Array& obj);
        int length();
        void setData(int index, int value);
        int getData(int index);
        ~Array();

// []===!=   项目中的难点
        int& operator[](int i);         // [] 重载
        Array& operator=(Array &a2);    // = 重载
        bool operator==(Array &a2);   // == 重载
        bool operator!=(Array &a2);   // != 重载

};
Arraycpp.cpp
#include "iostream"
#include "Array.h"
using namespace std;

Array::Array(int length)
{
        if (length < 0)
        {
                length = 0;
        }
        mLength = length;
        mSpace = new int;
}

Array::Array(const Array& obj)
{
        mLength = obj.mLength;
        mSpace = new int;

        for (int i = 0; i < mLength; i++)
        {
                mSpace = obj.mSpace;
        }
}

int Array::length()
{
        return mLength;
}

void Array::setData(int index, int value)
{
        mSpace = value;
}

int Array::getData(int index)
{
        return mSpace;
}

Array::~Array()
{
        mLength = -1;
        delete[] mSpace;
}

// [] 重载的实现   // 为了实现返回值当左值,需要返回应用
int& Array::operator[](int i)
{
        return mSpace;
}

//Array a3(100);
//a3 = a2;      // = 重载
// 1) 如果a3已经分配内存则需要释放
// 2) 根据a2开辟内存空间 把a2的值copy到a3中
Array& Array::operator=(Array &a2)   // 如果返回值不加引用,这里会多执行一次copy构造函数创建一个匿名对象, 场景4
{                                    // 需要返回值当左值,必须返回一个引用
        if (this->mSpace != NULL)
        {
                delete[] mSpace;
                mSpace = NULL;
                mLength = 0;
        }
        this->mLength = a2.mLength;
        this->mSpace = new int;

        for (int i = 0; i < this->mLength; i++)
        {
                mSpace = a2;
        }
        return *this;
}

// == 重载
bool Array::operator==(Array &a2)
{
        // 先判断a1和a2的长度是否相等
        // a1,a2中每个元素是否相等
        if (this->mLength != a2.mLength)
        {
                return false;
        }

        for (int i = 0; i < this->mLength; i++)
        {
                if (this->mSpace != a2)
                {
                        return false;
                }
        }
        return true;
}

bool Array::operator!= (Array &a2)
{
        return !(*this==a2);// 运算符重载也是一个函数

}
测试:ArrayTest.cpp
#include "iostream"
#include "Array.h"
using namespace std;

int main()
{
        Array a1(10), a3(10);

        for (int i = 0; i < a1.length(); i++)
        {
                //a1.setData(i, i);         // 想换成 a1 = i(函数返回值做左值)   [] 重载
                // int& operator[](int i)   // 函数返回值做左值 ===>   需要函数返回引用
                a1 = i;            
        }

        for (int i = 0; i < a1.length(); i++)
        {
                //printf("array %d: %d \n", i, a1.getData(i));
                cout << a1 << endl;
        }

        Array a2 = a1;   // 初始化 执行拷贝构造函数

        for (int i = 0; i < a2.length(); i++)
        {
                printf("array %d: %d \n", i, a2.getData(i));
        }

        if (a2 == a1)   // == 重载
        {
                printf("相等\n");
        }

        if (a3 != a1)   // == 重载
        {
                printf("不相等\n");
        }

        Array a4(100);
        // 连等操作
        a1 = a4 = a2;      // = 重载   (函数返回值做左值)
        //a1.operator=(a3,operator=(a2));与上面的语句等同

        system("pause");
        return 0;
}
页: [1]
查看完整版本: 033-C++之运算符重载2