C++实现string类

By AverageJoeWang
 标签:

一.概述与问题

1.1.概述

string类是实际编程当中最常用的一个类,本篇文章是本人学习类的基础之后对string类的实现,以此测试自身对类的理解和加深对string的用法的理解。

1.2.问题

  • string有哪些操作?

  • 实现过程中需要用到类的哪些函数?

二.分析与实现

2.1.类的声明

  • 定义一个char型的指针变量作为数据成员

  • string类中需要有无参与有参构造函数用来初始化对象

  • 复制构造函数在定义对象的时候从已经定义的对象中复制内容

  • 赋值运算符函数实现已经声明的对象从已经定义的对象复制内容

  • 需要有友元函数对类的数据成员的访问,以此输出测试结果

  • 析构函数在作用域或者程序结束时候对对象的销毁管理

类声明

class String
{
friend ostream & operator<<(ostream &os, String &str);//友元
public:
    String();//无参构造函数
    String(const char *cp);//有参构造函数

    String(const String &str);//复制构造函数

    ~String();//析构函数

    String & operator=(const String &pstr);//赋值运算符函数

private:
    char *_data;//数据成员
};

2.2.构造函数

String::String()//无参构造函数
{
    _data = NULL;
    _data = new char[1];
    _data[0] = '\0';
}

String::String(const char *cp)//带参数的构造函数
{
    _data = new char[strlen(cp) + 1];
    strcpy(_data, cp);
}

2.3.析构函数

  • 因为是new声明的数组,在销毁的时候需要用到delete [] _data;
String::~String()//析构函数
{
    if(_data != NULL)
    {
        delete [] _data;
   _data = NULL;
    }
}

2.4.复制构造函数

String::String(const String &str)//复制构造函数
{
    if(str._data == NULL)
        _data = NULL;
    else
    {
        _data = new char[strlen(str._data) + 1];
        strcpy(_data, str._data);
    }
}

2.5.赋值运算符函数

  • 首先查看赋值的对象是否相等

  • 不相等则需要判断是否为空指针

  • 然后申请新的空间,赋值

String & String::operator=(const String &pstr)//赋值运算符函数
{
    if(this == &pstr)
        return *this;

    if(_data != NULL)
    {
        delete [] _data;
        _data = NULL;
    }
    _data = new char[strlen(pstr._data) + 1];
    strcpy(_data, pstr._data);
    return *this;
}

2.6.友元函数

  • 利用文件流和友元函数访问并且输出数据成员
ostream & operator<<(ostream &os, String &str)//输出函数
{
    os<<str._data;
    return os;
}

三.测试与结果

测试main函数

int main()
{
    String s1;//调用无参构造函数
    cout << "s1 = " << s1 << endl;
    String s2("JoeWang");//调用有参构造函数
    cout << "s2 = " << s2 << endl;
    String s3 = s2;//调用复制构造函数
    cout << "s3 = " << s3 << endl;
    String s4("AverageJoeWang");//调用友残构造函数
    cout << "s4 = " << s4 << endl;
    s1 = s4;//调用赋值运算符函数
    cout << "s1 = " << s1 << endl;
    return 0;
}

结果

String()
s1 = 
String(const char *cp)
s2 = JoeWang
String(const String &str)
s3 = JoeWang
String(const char *cp)
s4 = AverageJoeWang
String & String::operator=(const String &pstr)
s1 = AverageJoeWang
String::~String()
String::~String()
String::~String()
String::~String()

四.总结

string有哪些操作?

  • 默认初始化,显示初始化,复制,赋值等,本类是实现string最基本的功能

实现过程中需要用到类的哪些函数?

  • 无参构造函数,有参构造函数,复制构造函数,赋值运算符函数,析构函数

五.函数附录

 ///
 /// @file    3_MyString_class.cpp
 /// @author  AverageJoeWang(AverageJoeWang@gmail.com)
 ///
#include <iostream>
#include <cstring>
using namespace std;

class String
{
friend ostream & operator<<(ostream &os, String &str);
public:
    String();
    String(const char *cp);

    String(const String &str);

    ~String();

    String & operator=(const String &pstr);

private:
    char *_data;
};

String::String()//无参构造函数
{
    cout << "String()" << endl;
    _data = NULL;
    _data = new char[1];
    _data[0] = '\0';
}

String::String(const char *cp)//带参数的构造函数
{
    cout << "String(const char *cp)" <<endl;
    _data = new char[strlen(cp) + 1];
    strcpy(_data, cp);
}

String::~String()//析构函数
{
    cout << "String::~String()" <<endl;
    if(_data != NULL)
    {
        delete [] _data;
   _data = NULL;
    }
}



String::String(const String &str)//复制构造函数
{
    cout << "String(const String &str)" << endl;
    if(str._data == NULL)
        _data = NULL;
    else
    {
        _data = new char[strlen(str._data) + 1];
        strcpy(_data, str._data);
    }
}


String & String::operator=(const String &pstr)//赋值运算符函数
{
    cout << "String & String::operator=(const String &pstr)" << endl;
    if(this == &pstr)
        return *this;

    if(_data != NULL)
    {
        delete [] _data;
        _data = NULL;
    }
    _data = new char[strlen(pstr._data) + 1];
    strcpy(_data, pstr._data);
    return *this;
}

ostream & operator<<(ostream &os, String &str)//输出函数
{
    os<<str._data;
    return os;
}


int main()
{
    String s1;//调用无参构造函数
    cout << "s1 = " << s1 << endl;
    String s2("JoeWang");//调用有参构造函数
    cout << "s2 = " << s2 << endl;
    String s3 = s2;//调用复制构造函数
    cout << "s3 = " << s3 << endl;
    String s4("AverageJoeWang");//调用友残构造函数
    cout << "s4 = " << s4 << endl;
    s1 = s4;//调用赋值运算符函数
    cout << "s1 = " << s1 << endl;
    return 0;
}