运算符重载(+、=、==、[]、<<、>>)&&关于堆区运用&&#define _CRT_SECURE_NO_WARNINGS

以前没有把类搞得很清楚,后来慢慢摸索了一下才弄懂一些了,顺便发出来,以后忘记了或者有新认识的时候可以再学习!!!

题目:

 

1.<<、>>运算符重载模板

friend ostream& operator<<(ostream& cout, CMyString& str);
friend istream& operator>>(istream& cin, CMyString& str);

2.+、=、==运算符重载模板

 CMyString/void/bool operator+/=/==(const CMyString& str/const char* str);

注意:返回值是啥就返回相应的东西,运算符左边为CMyString类型,右边为括号对应的类容(类/字符串)

3.#define _CRT_SECURE_NO_WARNINGS

严重性    代码    说明    项目    文件    行    禁止显示状态
错误    C4996    'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    Project1    D:\2022_12_12REINOVO_16th\1212测试\运算符重载案例\Project1\MyString.cpp    27    

我在CMyString.h里定义了#define _CRT_SECURE_NO_WARNINGS,如果没有定义vs2022(似乎vs1017以上都会这样)会提示我们一些函数使用不安全,比如strcpy/strcat这些函数,当我们定义了_CRT_SECURE_NO_WARNINGS之后,就考虑弃用禁用了strcpy_s/strcat_s一系列函数,则没有报错了。

4.关于堆区内存的处理,我们之所以会在堆区开辟内存,主要原因还是堆区可以存放更大内存的数据,但是用堆区必须要手动释放,如果用了char*p=new char[len],那就要delete[] p;p=NULL;去释放;又或者用malloc,需要用free()释放。栈区会自动释放内存。

以上就是我主要解决的一些问题,以下是完整代码可以直接跑!!!

//CMyString.h

#pragma once
#define _CRT_SECURE_NO_WARNINGS//考虑禁用弃用了strcat_s等一系列函数
#include <iostream>
using namespace std;

class CMyString
{
    //<<和>>的重载,友元函数的运用(似乎ostream&和istream&可以写作ostream和istream)
    friend ostream& operator<<(ostream& cout, CMyString& str);
    friend istream& operator>>(istream& cin, CMyString& str);
public:
    //CMyString A="123456"或者CMyString A("123456")
    CMyString(const char* str);

    //CMyString A(A0)
    CMyString(const CMyString& str);

    //CMyString A
    CMyString();

    //如果int m_size;是私有变量,那么就可以运用这个成员函数求长度
    int Length();

    //+号的运算符重载
    CMyString operator+(const char* str);//(CMyString)A+"123"满足
    CMyString operator+(const CMyString& str);//(CMyString)A+(CMyString)A0满足

    //=号的运算符重载,我们从=号左边的类的指针去改变其内部的值,可以用void不用返回任何值
    void operator=(const CMyString& str);
    void operator=(const char* str);

    //==运算符的重载,注意:这里==有字符串时和类字符串左右交换位置后需要另一个重载函数
    bool operator==(const CMyString& str);
    bool operator==(const char* str);
    //bool operator==(const CMyString& str);  //但是暂时写不出const char和类交换后的比较

    //[]的重载
    char& operator[](int index);
    
    //c_str()
    const char* C_str();
public:
    ~CMyString();//析构函数总是先析构离自己最近的一个变量
private:
    char* Pstring;
    int m_size;
};

//CMyString.cpp

#include "CMyString.h"

CMyString::CMyString(const char *str)
{
    this->Pstring = new char[strlen(str) + 1];
    strcpy(this->Pstring, str);
    this->m_size = strlen(str);
}

CMyString::CMyString(const CMyString& str)
{
    this->Pstring = new char[strlen(str.Pstring) + 1];
    strcpy(this->Pstring, str.Pstring);
    this->m_size = str.m_size;
}

//定义一个空的构造函数
CMyString::CMyString()
{  
    this->Pstring = NULL;
    this->m_size = 0;
}

//访问自身的长度
int CMyString::Length()
{
    int len=this->m_size;   
    return len;
}

CMyString CMyString::operator+(const char* str)
{
    int newLen = this->m_size + strlen(str) + 1;
    char* newStr = new char[newLen];
    memset(newStr, 0, newLen);
    strcat(newStr, this->Pstring);
    strcat(newStr, str);
    CMyString A(newStr);
    delete[] newStr;
    newStr = NULL;
    return A;
}

CMyString CMyString::operator+(const CMyString& str)//*不能写作&,&代表一个地址,而*代表指针
{
    int newLen = this->m_size + strlen(str.Pstring) + 1;
    char* newStr = new char[newLen];
    memset(newStr, 0, newLen);
    strcat(newStr, this->Pstring);
    strcat(newStr, str.Pstring);
    CMyString A(newStr);
    delete[] newStr;
    return A;
}

void CMyString::operator=(const CMyString& str)
{
    if (this->Pstring != NULL)
    {
        delete[] this->Pstring;
        this->Pstring = NULL;
    }   
    int newLen = str.m_size + 1;
    this->Pstring = new char[newLen];
    memset(this->Pstring, 0, newLen);
    strcpy(this->Pstring, str.Pstring);
    this->m_size = str.m_size;
    //若我们不用void而用CMyString,那可以return *this;
}

void CMyString::operator=(const char* str)
{
    if (this->Pstring != NULL)
    {
        delete[] this->Pstring;
        this->Pstring = NULL;
    }
    int newLen = strlen(str) + 1;
    this->Pstring = new char[newLen];
    memset(this->Pstring, 0, newLen);
    strcpy(this->Pstring, str);
    this->m_size = strlen(str);
}

bool CMyString::operator==(const CMyString& str)
{
    
    if (strcmp(this->Pstring, str.Pstring)==0 && (this->m_size == str.m_size))
        return true;
    return false;
}

bool CMyString::operator==(const char* str)
{
    if (strcmp(this->Pstring, str)==0 && (this->m_size == strlen(str)))
        return true;
    return false;
}


char& CMyString::operator[](int index)
{
    return this->Pstring[index];
}

const char* CMyString::C_str()
{
    const char* p;
    p = this->Pstring;
    return p;
}

CMyString::~CMyString()
{
    if (this->Pstring != NULL)//这里的判断是考虑this->Pstring没有被赋值的影响
    {
        delete[] this->Pstring;
        this->Pstring = NULL;
    }
}

ostream& operator<<(ostream& cout, CMyString& str)
{
    // TODO: 在此处插入 return 语句
    cout << str.Pstring;
    return cout;
}

istream& operator>>(istream& cin, CMyString& str)
{
    //判断内容是否为空,不是则清空
    if (str.Pstring != NULL)
    {
        delete[] str.Pstring;
        str.Pstring = NULL;
    }
    //让用户输入内容
    char newstr[1024];//栈内存最高为1024字节
    cin >> newstr;

    str.Pstring = new char[strlen(newstr) + 1];
    strcpy(str.Pstring, newstr);
    str.m_size = strlen(newstr);
    return cin;
}

主程序:

// Project6.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束
#include <iostream>
#include"CMyString.h"
using namespace std;

void initialization()//关于对一块内存的初始化问题
{
    char aa[100] = { 4 };//初始化并不等于给定了值,而是让内存里的地址不指向空
    //初始化只是对第一个值赋值为括号内的值,往后所有数据全为0;
    cout << aa[0] + 1 << endl;
    int a2[100];//int类型的数只能初始化为0或者-1;
    //原因是memset初始化是一个字节一个字节的赋值,当赋值为1时,实际初始化的值二进制为0001 0001 0001 0001,也就是16843009
    memset(a2, 1, 100);//memset可以初始化为其他数
    cout << a2[1] << endl;
}

void Go()
{
    CMyString A0 = "123";
    CMyString A1("456");    //A0和A1的构造函数一样都是  CMyString(const char* str);
    CMyString A2(A1);   //构造函数为 CMyString(const CMyString& str);
    CMyString A3;   //构造函数为 CMyString();
    //<<和>>重载分析
    cout << A0 << "\t" << A1 << endl;     //输出123     456

    //利用成员函数访问私有变量调用自身长度
    cout << A0.Length() << endl;  //输出 3

    //+运算符重载
    A3 = A0 + "123" + A1;   //调用+重载函数后,再调用=重载函数
    //"123"不能放到第一个位置,因为没有写这个重载方式
    cout << "A3等于" << A3 << endl;   //输出123456
    CMyString A4 = A0 + "789";
    cout << A4 << endl;   //输出123789

    //=运算符的重载
    //A3 = A0 + A1;

    //判断==符号重载
    CMyString A5 = "456";
    if (A1 == A5)
    {
        cout << "A1等于A5" << endl;
    }
    if (A0 == "123")
    {
        cout << "A0等于123" << endl;
    }
    //char& operator[](int index);[]的重载
    CMyString A6[5];
    A6[3] = "123456789";
    cout << "A6[3]" << A6[3] << endl << "A6[3]长度为:" << A6[3].Length() << endl;
    //A6[3]123456789
    //A6[3]长度为:9

    //C_str()的使用
    CMyString A7 = "www";
    const char* p;
    p = A7.C_str();
    cout << "A7改变前:" << endl;
    cout << "A7:" << A7 << endl;
    cout << "p:" << p << endl;
    A7 = "aaa";
    cout << "A7改变后:" << endl;
    cout << "A7:" << A7 << endl;
    cout << "p:" << p << endl;      //很明显,A7改变后,p也改变了,p总是指向A7的地址
}

int main()
{
    //关于一些初始化的问题
    //initialization();
    Go();
    return 0;
}

若有不周之处,欢迎讨论。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值