My_String类案例(构造、析构、重载'=' '[]' '<<' '==' '!=' '>' '<' '>>' 运算、操作符以及其他技巧)(重载完结)

这是一个字符串类的小案例

头文件 MyString.h

#ifndef MYSTRING_H_INCLUDED
#define MYSTRING_H_INCLUDED

#include <iostream>
using namespace std;

//c中没有字符串 (字符串类  c风格的字符串)
//空串
class MyString{
private:
    int m_len;
    char *m_p;
    friend ostream& operator<<(ostream& out, const MyString &obj);
    friend istream& operator>>(istream& in,  MyString &obj);

public:
    MyString();
    MyString(const char *p);
    MyString(const MyString &s);
    ~MyString();

    MyString& operator=(const MyString &obj);//用另一个的对象去等
    MyString& operator=(const char *p);//用字符串去等

    char operator[](int x);

    bool operator==(const MyString &obj);
    bool operator!=(const MyString &obj);

    bool operator>(const MyString &obj);//与另一个对象去比较
    bool operator>(const char *p);//与字符串去比较
    bool operator<(const MyString &obj);//与另一个对象去比较
    bool operator<(const char *p);//与字符串去比较

public:
    //技巧:怎么样把类的私有属性露出来
    char* c_str()
    {
        return m_p;
    }
    //假设露出来的指针变成只读属性
    const char* c_str2()
    {
        return m_p;
    }
    int length()
    {
        return m_len;
    }
};

#endif // MYSTRING_H_INCLUDED

MyString.cpp

#include <string.h>
#include "MyString.h"

//无参构造函数
//MyString s1;
MyString::MyString()
{
    m_len = 0;
    m_p = new char [m_len+1];
    strcpy(m_p, "");
}

//有参构造函数
//MyString s2("demo");
MyString::MyString(const char *p)
{
    if(p == NULL){
        m_len = 0;
        m_p = new char [m_len+1];
        strcpy(m_p, "");
    }
    else{
        m_len = strlen(p);
        m_p = new char[m_len+1];
        strcpy(m_p, p);
    }
}

//拷贝构造函数
//MyString s3 = s2;
MyString::MyString(const MyString &s)
{
    m_len = s.m_len;
    m_p = new char[m_len+1];
    strcpy(m_p, s.m_p);
}

//析构函数
MyString::~MyString()
{
    if(m_p != NULL){
        delete [] m_p;
        m_p = NULL;
        m_len = 0;
    }
}


//重载 = 运算符
//MyString s("fire");
//t = s;
//t = "cap";

MyString& MyString::operator=(const MyString &obj)
{
    if(m_p != NULL){//旧内存释放
        delete [] m_p;
        m_p = NULL;
        m_len = 0;
    }
    m_len = obj.m_len;
    m_p = new char[m_len+1];;
    strcpy(m_p, obj.m_p);
    return *this;
}

MyString& MyString::operator=(const char *p)
{
    if(m_p != NULL){//旧内存释放
        delete [] m_p;
        m_p = NULL;
        m_len = 0;
    }
    if(p == NULL){
        m_len = 0;
        m_p = new char[m_len+1];
        strcpy(m_p, "");
    }
    else{
        m_len = strlen(p);
        m_p = new char[m_len+1];
        strcpy(m_p, p);
    }
    return *this;
}


//重载 [] 运算符
//cout << "t[1]: " <<t[1] << endl;
char MyString::operator[](int x)
{
    if(x < 0 || x >= m_len)
        throw "询问越界";
    else{
        return m_p[x];
    }
}

//重载 << 操作符
// cout << s1 << s2 << s3 << t << endl;
ostream& operator<<(ostream& out, const MyString &obj)
{
    /*
    for(int i = 0; i < obj.m_len; i++)
        out << obj.m_p[i];
    */
    out << obj.m_p;
    return out;
}


//重载 == 和 != 逻辑运算符
bool MyString::operator==(const MyString &obj)
{
    if(m_len != obj.m_len)
        return false;
    else{
        for(int i = 0; i < m_len; i++)
            if(m_p[i] != obj.m_p[i])
                return false;
    }
    return true;
}

bool MyString::operator!=(const MyString &obj)
{
    if((*this) == obj)
        return false;
    return true;
}

//重载 > < 运算符
bool MyString::operator>(const MyString &obj)
{
    for(int i = 0; i < m_len && i < obj.m_len; i++){
        if(m_p[i] > obj.m_p[i])
            return true;
        if(m_p[i] > obj.m_p[i])
            return false;
    }
    if(m_len > obj.m_len)
        return true;
    else
        return false;
}

bool MyString::operator<(const MyString &obj)
{
    if((*this) > obj || (*this) == obj)
        return false;
    return true;
}

bool MyString::operator>(const char *p)
{
    int len = strlen(p);
    for(int i = 0; i < m_len && i < len; i++){
        if(m_p[i] > p[i])
            return true;
        if(m_p[i] > p[i])
            return false;
    }
    if(m_len > len)
        return true;
    else
        return false;
}

bool MyString::operator<(const char *p)
{
    if((*this) > p || (*this) == p)
        return false;
    return true;
}


//重载 >> 操作符
istream& operator>>(istream &in, MyString &obj)
{
    if(obj.m_p != NULL){
        delete [] obj.m_p;
        obj.m_p = NULL;
        obj.m_len = 0;
    }
    obj.m_p = new char[1000];
    in >> obj.m_p;
    obj.m_len = strlen(obj.m_p);
    return in;
}
main.cpp

#include <iostream>
#include <string.h>
#include "MyString.h"
using namespace std;

int main()
{

    //构造  and  析构
    MyString s1;
    MyString s2("demo");
    MyString s3 = s2;

    //重载 = 运算符
    MyString t;
    MyString s("fire");
    t = s;
    t = "cap";

    //重载 [] 操作符
    cout << "t[1]: " << t[1] << endl;

    //重载左移操作符
    cout << "s:" << s << "\ns1:" << s1 << "\ns2: " << s2 << "\nt: " << t << endl;

    //重载 == 和 != 逻辑运算符
    if(s1 == s2)    cout << "s1 " << "=="  << " s2" << endl;
    else  cout << "s1 " << "!="  << " s2" << endl;

    if(s1 != s2)    cout << "s1 " << "!="  << " s2" << endl;
    else  cout << "s1 " << "=="  << " s2" << endl;

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

    //其他技巧
    //假设我要实现: strcpy(s.m_p, "aaa111") 苦于指针是私有变量而无法实现
    //技巧:怎么样把类的私有属性露出来
    strcpy(s.c_str(), "f");//MFC
    cout << "s:" << s << endl;

    //重载 >> 操作符
    //首先,我们要分配好内存(在构造函数中进行)
    cout << "请用户输入 s : ";
    cin >> s;
    cout << "s:" << s << endl;

    return 0;
}


下面是运行结果




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你的自定义类型需要使用输入运算符 `>>` 进行输入,你需要重载输入运算符 `>>`。 重载运算符 `>>` 的格式一般如下: ``` istream& operator>>(istream& is, YourType& obj) { // 从输入流中读取数据,存储到 obj 中 // ... return is; } ``` 其中,`is` 是输入流对象,`obj` 是你的自定义类型对象。 这里使用了引用 `&`,是因为输入运算符需要修改输入流对象的状态,所以需要传入输入流对象的引用。 比如,如果你的自定义类型是一个名为 `Person` 的结体,你可以这样重载输入运算符 `>>`: ``` #include <iostream> using namespace std; struct Person { string name; string username; string password; string idnumber; }; istream& operator>>(istream& is, Person& p) { is >> p.name >> p.username >> p.password >> p.idnumber; return is; } int main() { Person p; cin >> p; // 使用重载的输入运算符 cout << p.name << " " << p.username << " " << p.password << " " << p.idnumber << endl; return 0; } ``` 上述代码中,`Person` 结体中包含了四个字符串类型的成员变量。在重载的输入运算符中,使用输入运算符 `>>` 依次读取输入流中的四个字符串,然后存储到 `Person` 对象中。在 `main` 函数中,使用重载的输入运算符 `>>` 从标准输入流 `cin` 中读取数据并存储到 `Person` 对象 `p` 中,然后输出 `Person` 对象的成员变量。 这样,你就可以使用 `ifs >> person` 的形式从输入流中读取数据并存储到 `Person` 对象中了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值