c++面試題:模擬實現String類(深拷貝)

本篇博客模擬實現一個String類,使用深拷貝的傳統與現代寫法。

深拷貝:重新開闢空間,將原來的空間拷貝過來,再把值複製過來,
此種方法兩個對象指向不同空間,析構時析構各自的數據塊,不會造成內存泄露問題。(稍後在代碼中解釋)

傳統寫法

思路:
使用傳統寫法:即老實人的寫法。
構造/拷貝構造/賦值運算符重載函數`先開闢空間再直接複製`
析構函數`如果_str!=NULL;釋放空間,並將_str置爲空,防止內存泄露`,所謂內存泄漏實際上丟失的是指針而非內存。

代碼實現:

#pragma once

//傳統寫法
class String
{
public:
    //構造函數
    String(char* str)
        :_str(new char[strlen(str) + 1])//開闢空間
    {
        strcpy(_str, str);
    }

    //拷貝構造函數
    //s2(s1)
    String(const String &s)
    {
        this->_str = new char[strlen(s._str) + 1];
        strcpy(_str, s._str);

    }

    //賦值運算符重載
    //s2=s1
    //s1=s1
    String& operator=(const String& s)
    {
        if (this != &s)//避免自身賦值
        {
            delete[] _str;
            _str = new char[strlen(s._str) + 1];
            strcpy(_str, s._str);
        }
        return *this;
    }
    //打印字符串
    const char* c_str()
    {
        return _str;
    }
    //析構函數
    ~String()
    {
        if (_str)
        {
            delete[] _str;
            _str = NULL;
        }

    }
private:
    char *_str;
};

//測試傳統寫法
void Test1()
{
    String s1 = "Just Right";
    String s2(s1);//調用拷貝構造函數,對象未存在
    cout << "s1:"<<s1.c_str() << endl;
    cout << "s2:" << s2.c_str() << endl;

    String s3("hello world");
    s1 = s3;//調用賦值運算符重載,對象已存在
    cout << "s1:" << s1.c_str() << endl;
    cout << "s3:" << s3.c_str() << endl;
}

這裏寫圖片描述
結果爲:
這裏寫圖片描述

現代寫法

思路:不開空間,藉助構造函數實現

//現代寫法

class String
{
public:
    String(char *str)
        :_str(new char[strlen(str)+1])
    {
        strcpy(_str, str);

    }
    //s2(s1)
    String(const String& s)
        :_str(NULL)
    {
        String tmp(s._str);//調用構造函數
        swap(_str, tmp._str);

    }
    //s2=s1
    String& operator=(const String& s)
    {
        if (this != &s)
        {
            String tmp(s._str);//調用構造函數
            swap(_str, tmp._str);
        }
        return *this;
    }
    ~String()
    {
        if (_str)
        {
            delete[] _str;
            _str = NULL;
        }
    }
    const char* c_str()
    {
        return _str;
    }
private:
    char *_str;
};

void Test2()
{
    String s1 = "hello world";
    String s2(s1);//調用拷貝構造函數,對象未存在
    cout << "s1:" << s1.c_str() << endl;
    cout << "s2:" << s2.c_str() << endl;

    String s3("1234");
    s1 = s3;//調用賦值運算符重載,對象已存在
    cout << "s1:" << s1.c_str() << endl;
    cout << "s3:" << s3.c_str() << endl;
}

分析:
這裏寫圖片描述
結果:
這裏寫圖片描述
這裏寫圖片描述
由上圖發現s1與s2指向不同空間

發佈了128 篇原創文章 · 獲贊 51 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章