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指向不同空间

猜你喜欢

转载自blog.csdn.net/kai29/article/details/80100897