• MyString的简单实现


     MyString.h 文件

    #ifndef _STRING_H_
    #define _STRING_H_
    #include <iostream>
    using namespace std;
    
    class MyString
    {
    public:
    	/*默认的无参和cons char *参数的构造函数;
    	*如果不想允许MyString str="abc"类型的赋值,可将其声明为explicit
    	*/
    	MyString(const char* str=""); 
    
    	//复制构造函数
    	MyString(const MyString& other);
    	
    	/*重载赋值操作符,
    	*返回值为自身的引用是为了支持连续赋值,如str1 = str2 =str3;
    	*返回值为const是为了禁止(str1=str2)=str3这样的等式
    	*/
    	const MyString& operator=(const MyString& other);
    	const MyString& operator=(const char* str);
    		 
    	bool operator!() const;  //重载!操作符, const函数内不会改变类的数据成员
    	
    	/* 重载[]操作符
    	*重载此操作符后可以使用下标访问对象元素,拥有和字符串数组相同的功能
    	*传入的值必须是无符号整数,返回一个char 引用是为了允许MyString str("abc"); str[0]='c';这样的赋值操作
    	*/
    	char& operator[](unsigned int index);
    	/*
    	*如果不想允许上面的赋值,可以返回const型,这样就只能读取了; 此外函数定义为const含有一个好处:可以被const对象访问;
    	*char ch =str[0];// 合法
    	*str[0]=ch; //非法
    	*/
    	const char& operator[](unsigned int index) const;  
    
    	/*重载+操作符,连接两个字符串
    	*为什么不把该重载函数设为类成员函数? 如果将+重载为成员函数,则左操作数必须为MyString类型
    	*同时,由于MyString有隐式类型转换构造函数,这里的两个参数可以使MyString类型的也可以是const char * 或者char *
    	*由语义可知,返回值不应为引用;
    	* 定义为友元是因为该函数需要访问类的私有成员,且该函数职位该类使用
    	*/
    	friend MyString operator+(const MyString& s1, const MyString& s2);
    /*重载+=操作符
    * 这里可以声明为类成员函数,因为左操作数肯定是MyString类型;
    */
    	MyString& operator+=(const MyString& other);
    	
    	//声明为友元函数是因为,不能再ostream内重载<< >> 操作符,返回引用是为了支持连续输出或输入
    	friend ostream& operator<<(ostream& os, const MyString& str);
    	friend istream& operator>>(istream& is, MyString& str);
    	~MyString(void);
    
    	void Display() const;
    	unsigned int length(){
    		return strlen(str_);
    	}
    private:
    	MyString& Assign(const char* str);
    	char* AllocAndCpy(const char* str);
    	char* str_;
    };
    
    #endif // _STRING_H_
    

      

    MyString.cpp 文件

    #pragma warning(disable:4996)
    #include "MyString.h"
    #include <string.h>
    //#include <iostream>
    //using namespace std;
    
    MyString::MyString(const char* str)
    {
        str_ = AllocAndCpy(str);
    }
    
    MyString::MyString(const MyString& other)
    {
        str_ = AllocAndCpy(other.str_);
    }
    
    const MyString& MyString::operator=(const MyString& other)
    {
        if (this == &other)  // 防止自我赋值
            return *this;
        
        return Assign(other.str_);
    }
    
    const MyString& MyString::operator=(const char* str)
    {
        return Assign(str);
    }
    
    MyString& MyString::Assign(const char* str)
    {
        
        char * newStr = AllocAndCpy(str);
        if(newStr != NULL){  
          delete[] str_; // 预防在分配内存是出错,在这里分配成功后再delete
          str_ = newStr;
        }
        return *this;
    }
    
    bool MyString::operator!() const
    {
        return strlen(str_) != 0;
    }
    
    char& MyString::operator[](unsigned int index)
    {
        //return str_[index];
        //non const 版本调用 const版本
    
        return const_cast<char&>(static_cast<const MyString&>(*this)[index]);
    }
    
    const char& MyString::operator[](unsigned int index) const
    {
        return str_[index];
    }
    
    MyString::~MyString()
    {
        delete[] str_;
    }
    
    char* MyString::AllocAndCpy(const char* str)
    {
        int len = strlen(str) + 1;
        char* newstr = new char[len];
        memset(newstr, 0, len);
        strcpy(newstr, str);
    
        return newstr;
    }
    
    void MyString::Display() const
    {
        cout<<str_<<endl;
    }
    
    MyString operator+(const MyString& s1, const MyString& s2)
    {
    
        MyString str = s1;
        str += s2;
        return str;
    }
    
    MyString& MyString::operator+=(const MyString& other)
    {
        int len = strlen(str_) + strlen(other.str_) + 1;
        char* newstr = new char[len];
        memset(newstr, 0, len);
        strcpy(newstr, str_);
        strcat(newstr, other.str_);
    
        delete[] str_;
    
        str_ = newstr;
        return *this;
    }
    
    ostream& operator<<(ostream& os, const MyString& str)
    {
        os<<str.str_;
        return os;
    }
    
    istream& operator>>(istream& is, MyString& str)
    {
        char tmp[1024];
        cin>>tmp;
        str = tmp;
        return is;
    }

    main.cpp

    #include "MyString.h"
    #include <iostream>
    using namespace std;
    
    int main(void)
    {
        //构造函数测试
        {
            MyString str;
            MyString str1="nihao";
            MyString str2("hello");
            MyString str3=str2;
            
            cout << "str: length:"<<str.length()<<" :"<<str<<endl;
            cout << "str1: length:"<<str1.length()<<" :"<<str1<<endl;
            cout << "str2: length:"<<str2.length()<<" :"<<str2<<endl;
            cout << "str3: length:"<<str3.length()<<" :"<<str3<<endl;
            /*输出
                str: length:0 :
                str1: length:5 :nihao
                str2: length:5 :hello
                str3: length:5 :hello
            */
        }
        // 操作符重载测试
        {
            MyString str1,str2,str3;        
            str3 =str2 = str1 = "hello";
            cout << str1 << " "<<str2<<" "<<str3<<endl;
            
            str1="";
            cout << !str1 << " : "<<!str2<<endl;
            
            str2[0] = 'H';
            str2 += "world";
            
            str3 = str2 + "!";
            cout << "str1: length:"<<str1.length()<<" :"<<str1<<endl;
            cout << "str2: length:"<<str2.length()<<" :"<<str2<<endl;
            cout << "str3: length:"<<str3.length()<<" :"<<str3<<endl;
            
            /*
            hello hello hello
            0 : 1
            str1: length:0 :
            str2: length:10 :Helloworld
            str3: length:11 :Helloworld!
            */        
        }
        //内存泄露测试
        {
            while(true){
                MyString str;
                MyString str1="nihao";
                MyString str2("hello");
                MyString str3=str2+str1;
             
                str1="hello world";
                str1.Display();
                str2 += str3;
             
            }
        }
        return 0;
    }

     参考文献:http://www.xuebuyuan.com/1591314.html

  • 相关阅读:
    读取XML字符串到临时表
    Golang学习笔记
    Golang环境配置Centos
    IntelliJ Idea 常用快捷键列表
    Elasticsearch的Groovy Script自定义评分检索
    MSSQL读取xml字符串到临时表
    通过反射给对象属性动态赋值总结(含可空属性)
    。。。。。
    指定位置输出函数
    DBhelper
  • 原文地址:https://www.cnblogs.com/gaoyanqing/p/4740220.html
Copyright © 2020-2023  润新知