天天看點

C++ string類實踐

自定義了一個MyString類:涉及到了一個類最基本的構造函數、析構函數、深拷貝,記憶體管理等問題。

頭檔案:

#ifndef MYSTRING_H

#define MYSTRING_H

#include <iostream>

#include <string.h>

using namespace std;

class MyString

{

public:

    friend ostream &operator<<(ostream &out, const MyString &obj);

    MyString(const char* str=NULL);    //ctor

    MyString(const MyString &obj);    //copy ctor

    ~MyString(); //dtor

    MyString& operator=(const MyString &obj);

    MyString substr(int start, int len);    //傳回char* 不好進行記憶體管理,采用類類型,借鑒string

    void setData(const char* str);

    void display();

private:

    char *m_data;

    int m_len;

};

#endif // MYSTRING_H

CPP檔案:

#include "MyString.h"

#include <iostream>

#include <string>

#include <string.h>

using namespace std;

ostream &operator<<(ostream &out, const MyString &obj)

{

    cout << obj.m_data;

    return out;

}

MyString::MyString(const char* str)//預設參數隻在聲明的時候寫上

{

    cout << "調用構造函數:";

    if (str == NULL)

    {

        m_data = NULL;

        return;

    }

    m_len = strlen(str) ;

    m_data = new char[m_len+1];

    strcpy(m_data, str);

    cout << m_data<<endl;

}

MyString::MyString(const MyString &obj)    //拷貝構造函數,使用深拷貝

{

    cout << "調用拷貝構造:";

    if (obj.m_data == NULL)

    {

        m_data = NULL;

        return;

    }

    m_len = strlen(obj.m_data); //這裡不能用sizeof,因為指針是無法求其指向内容的大小的,字元數組才可以。

    m_data = new char[m_len+1];

    strcpy(m_data, obj.m_data);

    cout << m_data << endl;

}

MyString & MyString::operator=(const MyString &obj)

{

    if (this != &obj)//檢查自指派

    {

        cout << "釋放原有記憶體..."<< endl;

        MyString temp(obj);    //離開作用于釋放記憶體,釋放的是原對象指向的記憶體

        char *ptemp = m_data;

        this->m_data = temp.m_data;

        temp.m_data = ptemp;

    }

    return *this;

}

MyString::~MyString()

{

    cout << "調用析構: "<< m_data << endl;

    if (m_data != NULL)

    {

        delete[]m_data;

        m_data = NULL;

    }

}

void MyString::display()

{

    cout << m_data << endl;

}

MyString MyString::substr(int start, int len)

{

    if (start < 0 || len < 0)

        return "";

    char* buf = new char[len + 1];

    int i = start;

    int j = start + len ;

    for (int k = i; k < j; k++)

    {

        buf[k - i] = m_data[k];

    }

    buf[len] = '\0';

    return MyString(buf);

}

void MyString::setData(const char* str)

{

    if (m_data != NULL)

    {

        cout << "釋放原有記憶體" << endl;

        delete m_data;

        m_data = NULL;

    }

    if (str == NULL)

        return;

    m_len = strlen(str);

    m_data = new char[m_len + 1];

    strcpy(m_data, str);

    cout << m_data << endl;

}

測試程式:

char p[1000] = { 0 };

    while (1)

    {

        memset(p, 0, sizeof(p));

        cout << "請輸入:(按q/Q退出)" << endl;

        cin.getline(p, 1000);

        if (!strcmp(p, "q") || !strcmp(p, "Q"))

            break;

        MyString s(p);//離開作用域自行調用析構函數

        cout << s.substr(0, 3) << endl;//這句話執行就調用析構

        cout << "***********" << endl;

        //s.display();

        MyString s1(s);

        //ss.display();

        cout<<"*******"<<endl;

        MyString s2 = s;

        cout<<"*******"<<endl;

        s2.setData("Hello world!");

        s1 = s2;

    }

繼續閱讀