STL之string模拟实现

学习过C++大家对STL应该是都不陌生,C++不学STL那就等于没学,今天是一片简单的string模拟实现,话不多说,直接上代码:

#pragma once
#include <iostream>
#include <cassert>
#include <cstdlib>
#include <string.h>
using namespace std;
namespace cc
{
    class string
    {
    friend istream& operator>>(istream& in,string& s);
    public:
    //迭代器
    typedef char* iterator;
    typedef const char* const_iterator;
        string(const char *str = "\0")
            : _str(new char[strlen(str)+1])
            , _capacity(strlen(str))
            , _size(_capacity)
        {
            strcpy(_str,str);
        }
        string(const string& d)
            : _str(nullptr)
        {
            string tem(d._str);
            swap(tem);
        }
        ~string()
        {
            delete[] _str;
            _str=nullptr;
            _capacity=_size=0;
        }
        string& operator=(string d)
        {
            swap(d);
            return *this;
        }
        iterator begin()
        {
            return _str;
        }
        iterator end()
        {
            return _str+_size;
        }
        const_iterator begin()const
        {
            return _str;
        }
        const_iterator end()const
        {
            return _str+_size;
        }
        void swap(string& d)
        {
            std::swap(_str,d._str);
            std::swap(_capacity,d._capacity);
            std::swap(_size,d._size);
        }
        size_t capacity()const
        {
            return (size_t)_capacity;
        }
        size_t size()const
        {
            return (size_t)_size;
        }
        char& operator[](const int& x)const
        {
            assert(x<(int)size());
            return *(_str+x);
        }
        char* c_str()const
        {
            return _str;
        }
        void resize(size_t n,const char* str="\0")
        {
            _size=n;
            for(size_t i=0;i<_size;i++)
                _str[i]=str[i];
        }
        void reserve(size_t n)
        {
            if(_str==nullptr)
            {
                _str=new char[5];
                _capacity=4;
                _size=4;
            }
            else if(n>capacity())
            {
                char *tem=new char[n];
                strcpy(tem,_str);
                delete[] _str;
                _str=tem;
                _capacity=strlen(_str);
                _size=_capacity;
            }
        }
        //运算符重载
        bool operator==(const string& d)const;
        bool operator<=(const string& d)const;
        bool operator!=(const string& d)const;
        //......
    private:
        char *_str;
        int _capacity;
        int _size;
        //此数组的作用类似于是缓冲区
        //char _buf[15];
    };
    //重载<<不能用友元函数
    ostream& operator<<(ostream& out,const string& s)
    {
        size_t i=0;
        for(i=0;i<s.size();i++)
            out<<s[i];
        return out;
    }
    //方法一:
    // istream& operator>>(istream& in,const string& s)
    // {
    //     char ch;
    //     ch=in.get();
    //     //这里最好加上一个缓冲区(缓冲区用数组来代替,目的是提高效率)
    //     while(ch!=' '&&ch!='\n')
    //     {
    //         //s+=ch;
    //         ch=in.get();
    //     }
    //     return in;
    // }
    //方法二:
    istream& operator>>(istream& in,string& s)
    {
        in>>s._str;
        return in;
    }
}

功能没有实现全面,但是只是一些简单的功能函数没有实现,主要的都已经实现。现在就说说string模拟实现中的一些关键性问题:

首先就是,string是深拷贝,这个很简单,深浅拷贝在前面已经浅浅的说过一些了,深拷贝其实就是要让他们指向的空间不一样,这样析构的时候就没有错误了。

还有就是,大家一定要注意的是,在重载流插入和流提取的运算符时,个人认为插入既可以用友元函数,也可以自己写,上面有两种方法的代码,而在自己实现的过程中,一定要注意的是,cin其实是忽略空格和换行的,所以此时就要用到的是cin中的一个成员函数。而我写的那个数组其实就是类似于一个缓冲区的东西,类似于减少IO次数,提高效率的作用。而流提取不可以用友元函数,因为string中的打印是有多少打印多少,而不是遇见‘\0’就结束,这个一定要注意。(这里谨记,一定要少用友元函数,因为其破坏了封装)。所以还是建议自己实现,不要用友元函数。

而还要注意的是string中的容量其实是比显示的容量大的,因为还有一个'\0',还有就是,仔细的小伙伴可能看到我私有成员变量中还写了一个数组,这个其实很简单,这个其实也是类似于一个缓冲区,因为每次扩容所付出的代价极大,所以我们也可以定一个数组来充当缓冲区,这样就会好很多。而vs2013,2019等环境下,其实我们可以看到源码,其中就有这个数组来充当缓冲区,所以我们也可以模拟一下。

上面是string的注意事项,如果本篇内容对你们有用的话,希望大家点一下赞,支持一下!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,我来帮您解答这个问题。 首先,我们需要定义一个学生类,包含学生的基本信息以及相关成绩信息: ```c++ #include <string> #include <vector> #include <iostream> using namespace std; class Student { public: string name; // 学生姓名 int age; // 学生年龄 vector<int> scores; // 存储学生各门课的成绩 // 构造函数 Student(string name, int age) : name(name), age(age) {} // 计算平均成绩 double avg_score() const { double sum = 0.0; for(int score : scores) { sum += score; } return scores.empty() ? 0.0 : sum / scores.size(); } // 输出学生信息 friend ostream& operator<<(ostream& os, const Student& student) { os << "Name: " << student.name << ", Age: " << student.age << ", Scores: "; for(int score : student.scores) { os << score << " "; } os << ", Avg Score: " << student.avg_score(); return os; } }; ``` 接下来,我们需要模拟上课过程,即随机生成学生的成绩,并将其存储到容器中: ```c++ #include <random> // 模拟上课过程,随机生成学生的成绩 void simulate_class(vector<Student>& students) { // 随机数生成器 random_device rd; mt19937 gen(rd()); uniform_int_distribution<> dis(0, 100); // 遍历学生,生成成绩 for(auto& student : students) { for(int i = 0; i < 5; i++) { student.scores.push_back(dis(gen)); } } } ``` 最后,我们需要使用STL库的相关容器对数据进行存储,并将数据保存到文件中: ```c++ #include <fstream> // 从文件中读取学生信息 void read_students(const string& filename, vector<Student>& students) { ifstream fin(filename); string name; int age, score; while(fin >> name >> age) { Student student(name, age); while(fin >> score) { student.scores.push_back(score); } students.push_back(student); } fin.close(); } // 将学生信息保存到文件中 void save_students(const string& filename, const vector<Student>& students) { ofstream fout(filename); for(const auto& student : students) { fout << student.name << " " << student.age << " "; for(int score : student.scores) { fout << score << " "; } fout << endl; } fout.close(); } int main() { vector<Student> students; // 从文件中读取学生信息 read_students("students.txt", students); // 模拟上课过程 simulate_class(students); // 将学生信息保存到文件中 save_students("students.txt", students); // 输出学生信息 for(const auto& student : students) { cout << student << endl; } return 0; } ``` 以上就是基于C++定义一个学生类,实现上课过程的模拟和平时成绩的计算,应用STL库的相关容器对数据进行存储,程序数据可以保存到文件中,开始程序时自动读取的全部代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值