C++运算符重载练习 数组类Array 字符串类Mystring

前言:

仅做记录和分享自己学习的过程,学艺不精,code新人,如有错误欢迎在评论区讨论、指正!

C++中预定义的操作符对象只能是基本数据类型,想要对自定义的类进行相似的运算操作,需要重新定义这些运算符,实现想要的运算功能(本质类似函数重载)

一、运算符重载实现的方式

1.成员函数实现

a1+a2           相当于 a1.operator+(a2), 在A类中实现该函数

语法形式:

class 类名

{

        返回类型 operator运算符(形参表);

}

类外定义格式

返回类型 类名::operator运算符(形参表)

{

        函数体;

}

2.友元函数实现

a1+a2   相当于operator+(a1,a2),在全局函数中实现

class 类名

{

        friend 返回类型 operator运算符(形参表);

}

类外定义格式

返回类型 operator运算符(形参表)

{

        函数体;

}

对于成员函数重载运算符而言,双目运算符的参数表中仅有一个参数,而单目则无参数。同样的是重载,友元函数在参数的个数上会有所区别的。原因在于友元函数,没有this指针。

二、特殊的成员函数

特殊在,如果没有自己写,编译系统会自动生成简单的默认版本,默认版本功能比较简单,只能保证基本的编译通过,当涉及到空间的开辟和销毁时,最好自己写这些函数。

1.构造函数

默认的构造函数,没有参数, 没有做事情

例如,A();

2.析构函数

默认的析构函数,没有参数, 没有做事情 

例如 ,~A();

3.拷贝函数

默认的拷贝构造, 浅拷贝,相当于直接赋值,不会开空间,如果在值里面有指针会造成,多变量指向同一空间,在析构的时候可能多次释放同一片空间,造成错误。

4.赋值函数

默认的赋值函数, 浅拷贝

三、运算符重载实践题

1.数组类Array

完善数组类,实现==, + , +=, [],=,支持cout输出

实现结果截图:

实现代码:
#include <iostream>
using namespace std;
// 设计一个数组类
class Array // 类的声明
{
private:
    int *data;  // 数组指针,指向数组数据
    int length; // 数组长度
    int index;//数组最大下标
public:
    Array();              // 无参构造函数
    Array(int len);       // 有参构造函数
   Array(int *b, int n); // 拷贝构造函数,传入一个数组
   Array(const Array &obj); // 拷贝构造函数,传入一个对象
    ~Array();             // 析构函数
    friend ostream &operator<<(ostream &out,const Array &obj);
    friend istream &operator>>(istream &in, Array &obj);
    Array &operator=(const Array &obj) // 重载+运算符
    {
        delete[] data;
        int n = obj.index;
        index = n;
        length = n + 1;
        data = new int[length];//动态分配内存
        for (int i = 0; i <= n; i++)//赋值
        {
            data[i] = obj.data[i];
        }
        return *this;
    }
    Array operator+(const Array &obj) // 重载+运算符
    {
        Array arr1;//创建一个新数组对象
        arr1.length = index + obj.index + 2;
        arr1.index = arr1.length - 1;
        arr1.data = new int[arr1.length];
        for (int i = 0; i <= index; i++)
        {
            arr1.data[i] = data[i];
        }
        for (int i = 0; i <= obj.index; i++)
        {
            arr1.data[index + 1 + i] = obj.data[i];
        }

        return arr1;
    }
    Array &operator+=(const Array &obj) // 重载+=运算符
    {
        // 在原对象的基础上进行操作
        int *new_data = new int[index + obj.index + 2]; // 创建新数组
        int new_length = index + obj.index + 2;
        int new_index = index + obj.index + 1;
        for (int i = 0; i <= index; i++) // 将原数组元素复制到新数组
        {
            new_data[i] = data[i];
        }
        for (int i = 0; i <= obj.index; i++) // 将新数组元素复制到新数组
        {
            new_data[index + 1 + i] = obj.data[i];
        }
        delete[] data;   // 释放原数组
        data = new_data; // 更新当前对象
        length = new_length;
        index = new_index;
        return *this;
    }
    bool operator==(const Array &obj)// 重载==运算符
    {
        if (index == obj.index && length == obj.length)
        {
            for (int i = 0; i < index; i++)
            {
                if (data[i] != obj.data[i])
                    return false;
            }
            return true;
        }
        else
        {
            return false;
        }
    }
    int& operator[](int index)// 重载[]运算符
    {
        if (index >= 0 && index <= this->index)
            return data[index];
        else
        {
            cout << "数组越界" << endl;
            exit(0);
        }
    }
};
Array::Array() // 无参构造函数
{
    length = 10;
    data = new int[length];
    index = -1;
    // cout << "调用无参构造函数" << endl;
}

Array::Array(int len) // 开辟空间
{
    data = new int[len];
    length = len;
    index = -1;
    // cout << "调用有参构造函数" << endl;
}

Array::Array(int *b, int n) // 拷贝构造函数,传入一个数组
{
    data = new int[n];
    length = n;
    for (int i = 0; i < n; i++)
    {
        data[i] = b[i];
    }
    index = n - 1;
    // cout << "调用拷贝构造函数" << endl;
}
Array::~Array() // 析构函数
{
    delete[] data; // 回收数组空间
    // cout << "调用析构函数" << endl;
}
Array::Array(const Array &obj)
{
    data = new int[obj.length];
    for (int i = 0; i <= obj.index; i++)
    {
        data[i] = obj.data[i]; // 拷贝数组  
    }
    length = obj.length;
    index = obj.index;
    cout << "调用拷贝构造函数" << endl;
}

ostream &operator<<(ostream &out, const Array &obj)
{
    for (int i = 0; i <= obj.index; i++)
    {
        out << obj.data[i] << " ";
    }
    return out;
}
istream &operator>>(istream &in, Array &obj)
{
    in >> obj.index;
    for (int i = 0; i <= obj.index; i++)
    {
        in >> obj.data[i];
    }
    return in;
}

int main(void)
{
    int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int b[5] = {11, 22, 33, 44, 55};
    Array a1; // 初始化
    Array a2(b, 5);
    Array a3(a, 10);
    a1 = a3; // 赋值
    cout << "a1:" << a1 << endl;
    cout << "a2:" << a2 << endl;
    cout << "a3:" << a3 << endl;
    Array a4=a3 + a2;
    cout << "a4 = a3 + a2 = :" << a4 << endl;
    a1 += a1;
    cout << "a1 += a1 = :" << a1 << endl;
    if (a1 == a2)
    {
        cout << "a1==a2" << endl;
    }
    else
    {
        cout << "a1!=a2" << endl;
    }
    cout << "a1[0]="<<a1[0] << endl;
    a1[0] = 100;
    cout << "a1[0]="<<a1[0] << endl;
    cout << "a1[20]="<<a1[20] << endl;

    return 0;
}

2.字符串类Mystring

编写Mystring类,实现+,+=,==,=,cout输出,cin输入

实现结果截图:

实现代码:
#include<iostream>
#include<cstring>
#include<cstdlib>
using namespace std;

class Mystring
{
public:
Mystring()//无参构造函数
{
    str=new char[1];
    *str='\0';
}
Mystring(const char *s)//有参构造函数
{
    int n = strlen(s);
    str=new char[n+1];
    strcpy(str,s);
}
Mystring(const Mystring & obj)//拷贝构造函数,一个对象初始化另一个对象
{
    int n=strlen(obj.str);
    str=new char[n+1];
    strcpy(str,obj.str);
}
~Mystring()//析构函数
{
    delete [] str;
}
void ShowString() const//显示
{
    cout<<str<<endl;
}
int length() const//长度
{
    return strlen(str);
}
Mystring operator+(const Mystring &obj) const    //+重载
{
    Mystring temp;
    delete [] temp.str;//释放原本的空间空间
    temp.str=new char[strlen(str)+strlen(obj.str)+1];//开辟新空间
    strcpy(temp.str,str);
    strcat(temp.str,obj.str);
    return temp;
}
Mystring & operator+=(const Mystring &obj)//+=重载,开辟新的空间,释放原来的空间
{ 
    char *new_str=new char[strlen(str)+strlen(obj.str)+1];
    strcpy(new_str,str);
    strcat(new_str,obj.str);
    delete [] str;
    str=new_str;//重新赋值,浅拷贝,空间转让
    return *this;
}
bool operator==(const Mystring &obj) const  //==重载,判断
{
    if(strcmp(str,obj.str)==0)
    return true;
    else
    return false;
}
Mystring & operator=(const Mystring &obj)   //=重载,深拷贝,释放原来的空间,开辟新的空间
{
    if(this==&obj)
    {
        return * this;
    }
    delete [] str;//释放原来的空间
    int n=strlen(obj.str);
    str=new char[n+1];
    strcpy(str,obj.str);
    return *this;
}
friend ostream& operator<<(ostream &out,const Mystring &obj); //cout<<重载
friend istream& operator>>(istream &out,Mystring &obj);//cin>>重载
private:
    char *str;
};
ostream& operator<<(ostream &out,const Mystring &obj)
{
    out<<obj.str;
    return out;
}
istream& operator>>(istream &in,Mystring &obj)//输入流重载,开空间
{
    char buf[1024];
    in>>buf;
    int n=strlen(buf);
    delete [] obj.str;
    obj.str=new char[n+1];
    strcpy(obj.str,buf);
    return in;
}
int main()
{
    Mystring s1("aaa");//有参构造
    cout<<"s1="<<s1<<endl;
    Mystring s2("xxx");
    cout<<"s2="<<s2<<endl;
    Mystring s3;//无参构造
    cout<<"请输入s3的值:"<<endl;   
    cin>>s3;
    cout<<"s3="<<s3<<endl;
    Mystring s4(s1);//拷贝构造
    cout<<"s4="<<s4<<endl;

    Mystring str1=s1+s2;//+运算符重载
    cout<<"str1=s1+s2="<<str1<<endl;

    str1+=str1;//+=运算符重载
    cout<<"str1+=str1="<<str1<<endl;
    
    if(s1==s2)//==运算符重载
    {
        cout<<"s1==s2"<<endl;
    }else
    {
        cout<<"s1!=s2"<<endl;
    }

    s2=s1;//赋值函数
   cout<<"s2=s1="<<s2<<endl;
   
}

                        ​​​​​​​        ​​​​​​​        ​​​​​​​        ​​​​​​​      

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值