C++ String 類的簡單實現

String類裏面主要包含構造,拷貝構造,析構,賦值,比較,字符串相加,獲取長度及子串等方法。

#include <iostream>
#include <cstring>
using namespace std;

class String{
public:
    // 默認構造函數
    String(char *str = NULL);
    // 複製構造函數
    String(String &str);
    // 析構函數
    ~String();
    // 字符串連接
    String operator+(const String & str);
    // 字符串賦值
    String& operator=(const String &str);
    // 判斷是否字符串相等
    bool operator==(const String &str);
    // 獲取字符串長度
    int length();
    // 求子字符串[start,start+n-1]
    String substr(int start, int n);
    // 重載輸出
    friend ostream & operator<<(ostream &o,const String &str);
private:
    char* m_data;
    int m_size;
};

// 構造函數
String::String(char *str = NULL){
//空構造也會創建一個長度爲1的字符串數組
    if(str == NULL){
        m_data = new char[1];
        m_data[0] = '\0';
        m_size = 0;
    }
    else{
        m_size = strlen(str);
        m_data = new char[m_size + 1];
        strcpy(m_data,str);
    }
}

//拷貝構造函數
String::String(const String &str){
    m_size = str.m_size;
    m_data = new char[m_size + 1];
    strcpy(m_data, str.m_data);
}

//析構函數
String::~String(){
    delete[] m_data;
}

// 字符串連接
//這裏返回的不是引用,而是值
String String::operator+(const String &str){
    String newStr;
    //釋放原有空間
    delete[] newStr.m_data;
    //創建長度爲兩個字符串長度和的空間大小
    newStr.m_size = m_size + str.m_size;
    newStr.m_data = new char[newStr.m_size + 1];
    strcpy(newStr.m_data, m_data);
    strcpy(newStr.m_data + m_size, str.m_data);
    return newStr;
}

//賦值函數
/*
這裏爲什麼返回對象的引用呢?原因有兩個:①允許進行連續賦值 ②防止返回對象(返回對象也可以進行連續賦值)的時候調用拷貝構造函數和析構函數導致不必要的開銷,降低賦值運算符等的效率。
對於第二點原因:如果用“值傳遞”的方式,雖然功能仍然正確,但由於return語句要把 *this拷貝到保存返回值的外部存儲單元之中,增加了不必要的開銷,會降低賦值函數的效率。
因此,如果賦值運算符返回的是對象引用,那麼其不會調用類的拷貝構造函數,這是問題的關鍵所在!!
*/

String& String::operation=(const char * str){
    if (m_data == str){
    return *this;
    }
    delete[] m_data;
    m_size = strlen(str);
    m_data = new char[m_size + 1];
    strcpy(m_data, str);
    return *this;
}

//判斷是否相等
bool String::operation==(const char *str){
    return strcmp(m_data, str.m_data) == 0;
}

//獲取長度
int String::length(){
    return m_size;
}

//求子字符串[start,start+n-1]
String String::substr(int start, int n){
    String newStr;
    //釋放原有內存
    delete[] newStr.m_data;
    //重新申請內存
    newStr.m_data = new char[n + 1];
    for (int i = 0; i < n; i++){
        newStr.m_data[i] = m_data[start + i];   
    }
    newStr.m_data[n] = '\0';
    newStr.m_size = n;
    return newStr;
}

// 重載輸出
ostream & operator<<(ostream &o, const String &str){
    o<<str.data;
    return o;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章