C++String类的实现

实现一个String类

String类原型:

class String
{
private:
    char * str;             // pointer to string
    int len;                // length of string
    static int num_strings; // String类对象数量
    static const int CINLIM = 80;  // cin input limit   输入限制
};

需要实现的功能:

  1. 实现char*和String类的构造,提供无参构造
  2. 实现=,[],>,<,==,<<,>>,运算符重载
  3. 功能函数
函数名 功能
append 将字符添加到字符串的末尾。
assign 将字符添加到字符串的末尾。
at 返回对字符串中指定位置的元素的引用。
begin 返回一个迭代器,寻址字符串中的第一个元素。
c_str 将字符串的内容转换为C样式,以null终止的字符串。
capacity 返回在不增加字符串的内存分配的情况下可以存储在字符串中的最大元素数。
cbegin 返回一个指向字符串中第一个元素的const迭代器。
cend 返回一个常量迭代器,该迭代器可寻址字符串中最后一个元素之后的位置。
clear 擦除字符串的所有元素。
compare 将字符串与指定字符串进行比较,以确定两个字符串是否相等,或者在字典上小于另一个。
copy 从源字符串中的索引位置最多复制指定数量的字符到目标字符数组。
crbegin 返回一个常量迭代器,该迭代器处理反向字符串中的第一个元素。
crend 返回一个常量迭代器,该迭代器寻址反向字符串中最后一个元素之后的位置。
data 将字符串的内容转换为字符数组。
empty 测试字符串是否包含字符。
end 返回一个迭代器,该迭代器寻址字符串中最后一个元素之后的位置。
erase 从指定位置删除字符串中的一个元素或元素范围。
find 在向前方向的字符串中搜索与指定字符序列匹配的子字符串的首次出现。
front 返回对字符串中第一个元素的引用。
insert 在字符串中的指定位置插入一个或多个元素或一系列元素。
length 返回字符串中的当前元素数。
max_size 返回字符串可以包含的最大字符数。
pop_back 擦除字符串的最后一个元素。
push_back 在字符串末尾添加一个元素。
rbegin 返回一个迭代器,该迭代器返回反向字符串中的第一个元素。
rend 返回一个迭代器,该迭代器指向恰好超出反向字符串中最后一个元素的位置。
replace 将指定位置的字符串中的元素替换为指定字符或从其他范围或字符串或C字符串复制的字符。
reserve 将字符串的容量设置为至少等于指定数字的数字。
resize 指定字符串的新大小,并根据需要添加或删除元素。
rfind 向后搜索字符串,查找与指定字符序列匹配的子字符串的首次出现。
size 返回字符串中的当前元素数。
substr 从指定位置开始的字符串中复制最多包含一些字符的子字符串。
swap 交换两个字符串的内容。

String类示例:

// string1.h -- fixed and augmented string class definition

#ifndef STRING_H_
#define STRING_H_
#include <iostream>
using std::ostream;
using std::istream;

class String
{
private:
    char * str;             // pointer to string
    int len;                // length of string
    static int num_strings; // String类对象数量
    static const int CINLIM = 80;  // cin input limit   输入限制
public:
// constructors and other methods
    String(const char * s); // constructor
    String();               // default constructor
    String(const String &); // copy constructor
    ~String();              // destructor
    int length () const { return len; }
    int size() const { return len; }
// overloaded operator methods    
    String & operator=(const String &);
    String & operator=(const char *);
    char & operator[](int i);
    const char & operator[](int i) const;
    String & operator+(const String &st);
    String & operator+(const char *s);
// overloaded operator friends
    friend bool operator<(const String &st, const String &st2);
    friend bool operator>(const String &st1, const String &st2);
    friend bool operator==(const String &st, const String &st2);
    friend bool operator==(const String &st, const char *st2);
    friend ostream & operator<<(ostream & os, const String & st);
    friend istream & operator>>(istream & is, String & st);
// static function
    static int HowMany();
public:
    //功能函数
    void append(const String &st);  //追加字符串
    void append(const char*s);      //追加字符串

    void push_back(const char ch);  //追加字符
    void swap(char* s);             //交换值
    void swap(String& st);          //交换值
    int find(const char*s, size_t index);   //寻找字符串
    int find(const String&st, size_t index);//寻找字符串
};
#endif
// string1.cpp -- String class methods
#include <cstring>                 // string.h for some
#include "string.h"               // includes <iostream>
using std::cin;
using std::cout;

// initializing static class member

int String::num_strings = 0;

// static method
int String::HowMany()
{
    return num_strings;
}

void String::append(const String & st)
{
    strcat(this->str, st.str);
    this->len = strlen(this->str);
    return;
}

void String::append(const char * s)
{
    strcat(this->str, s);
    this->len = strlen(this->str);
    return;
}

void String::push_back(const char ch)
{
    strcat(this->str, &ch);
    this->len = strlen(this->str);
    return;
}

void String::swap(char * s)
{
    char temp[CINLIM];
    strcpy(temp, this->str);
    strcpy(this->str,s);
    strcpy(s, temp);
    this->len = strlen(this->str);
    return;
}

void String::swap(String & st)
{
    char temp[CINLIM];
    strcpy(temp, this->str);
    strcpy(this->str, st.str);
    strcpy(st.str, temp);
    this->len = strlen(this->str);
    st.len = strlen(st.str);
    return;
}

int String::find(const char * s, size_t index)
{
    int length = strlen(s);
    for (int this_index = index; this_index < this->len; this_index++)
    {
        if (this->str[this_index] == s[0])
        {
            for (int s_index = 0; s_index < length; s_index++)
            {
                if (this->str[this_index + s_index] != s[s_index])
                    break;
                if (s_index == length - 1)  //匹配字符串
                    return this_index;
            }
        }
    }
    return -1;
}

int String::find(const String & st, size_t index)
{
    int length = strlen(st.str);
    for (int this_index = index; this_index < this->len; this_index++)
    {
        if (this->str[this_index] == st.str[0])
        {
            for (int s_index = 0; s_index < length; s_index++)
            {
                if (this->str[this_index + s_index] != st.str[s_index])
                    break;
                if (s_index == length - 1)  //匹配字符串
                    return this_index;
            }
        }
    }
    return -1;
}

// class methods
String::String(const char * s)     // construct String from C string
{
    len = std::strlen(s);          // set size
    str = new char[len + 1];       // allot storage
    std::strcpy(str, s);           // initialize pointer
    num_strings++;                 // set object count
}

String::String()                   // default constructor
{
    len = 4;
    str = new char[1];
    str[0] = '\0';                 // default string
    num_strings++;
}

String::String(const String & st)
{
    num_strings++;             // handle static member update
    len = st.len;              // same length
    str = new char [len + 1];  // allot space
    std::strcpy(str, st.str);  // copy string to new location
}

String::~String()                     // necessary destructor
{
    --num_strings;                    // required
    delete [] str;                    // required
}

// overloaded operator methods    

// assign a String to a String
String & String::operator=(const String & st)
{
    if (this == &st)
        return *this;
    delete [] str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}

// assign a C string to a String
String & String::operator=(const char * s)
{
    delete [] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}

// read-write char access for non-const String
char & String::operator[](int i)
{
    return str[i];
}

// read-only char access for const String
const char & String::operator[](int i) const
{
    return str[i];
}

String & String::operator+(const String & st)
{
    // TODO: 在此处插入 return 语句
    strcat(this->str, st.str);
    return *this;
}

String & String::operator+(const char * s)
{
    // TODO: 在此处插入 return 语句
    strcat(this->str, s);
    return *this;
}

// overloaded operator friends

bool operator<(const String &st1, const String &st2)
{
    return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator>(const String &st1, const String &st2)
{
    return st2 < st1;
}

bool operator==(const String &st1, const String &st2)
{
    return (std::strcmp(st1.str, st2.str) == 0);
}

bool operator==(const String & st, const char * st2)
{
    return (strcmp(st.str, st2) == 0);
}

// simple String output
ostream & operator<<(ostream & os, const String & st)
{
    os << st.str;
    return os; 
}

    // quick and dirty String input
istream & operator>>(istream & is, String & st)
{
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
        st = temp;
    while (is && is.get() != '\n')
        continue;
    return is; 
}

测试代码:

//main.cpp
#include<iostream>
#include"string.h"
int main()
{
    String s1 = "123";
    String s2("abc");
    String* s3 = new String("xyz");
    //赋值
    s1 = s2;   //相比C strcpy 更方便
    //比较
    if (s1 == s2)
    {
        cout << "s1 = s2" << endl;
    }
    cout << "===========拼接字符串============" << endl;
    s1 = s1 + "456";
    cout << s1 << endl;
    s1.append("789");
    cout << s1 << endl;
    s1.push_back('!');
    cout << s1 << endl;
    //交换
    cout << s1 << " " << s2 << endl;
    cout << "===========交换字符串============" << endl;
    s1.swap(s2);
    cout << s1 << " " << s2 << endl;
    //字符串长度
    cout << s2.size() << endl;
    //查找 替换

    cout << "===========寻找字符串============" << endl << s2.find("456", 0) << endl;
    cin.get();
    return 0;
}

测试结果:

s1 = s2
===========拼接字符串============
abc456
abc456789
abc456789!
abc456789! abc
===========交换字符串============
abc abc456789!
10
===========寻找字符串============
3
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354