一个简单的string类,读书看报系列(一)
对于这个类,写过程序的都知道应该含有的方法是
初始化、销毁、拼接、求长度、清除、判断是否为空等、还有一些操作符重载
一、先看初始化:
可以想到应该有默认构造的的、带有字符串的、带有默认字符的、还有一个拷贝构造函数
string()
string(const char * sc, intlength);
string(const char * sc);
string(char c);
string(const string& s);
~string();
我们可以分别写5个initialize函数,去对应这些构造函数
void initialize() { data = emptystr; }void initialize(const char*, int);void initialize(const char*);void initialize(char);void initialize(const string& s);
二、销毁
~string()
写一个函数finalize,让其在销毁的时候执行
三、成员变量
很简单就一个char*data就足够了,写成protected类型的
四、看看他的实现
写一个myString.cpp去对应这个ptypes.h
void string::initialize(const char* sc)
{initialize(sc, hstrlen(sc));
}void string::initialize(const char* sc, int initlen)
{if (initlen <= 0 || sc == nil){data = emptystr;}else{_alloc(initlen);memmove(data, sc, initlen);}
}void string::initialize(char c)
{_alloc(1);data[0] = c;
}void string::initialize(const string& s)
{data = s.data;pincrement(&STR_REFCOUNT(data));
}
那么现在构造函数算是完成了
看看里面,动态分配内存的函数(这里也是string的成员函数)
void _alloc(int);
void _realloc(int);
void _free(int);
从上面上看用处显而易见
void string::_alloc(int numchars)
{if (numchars <= 0){stringoverflow();}size_t a = quantize(numchars);
#ifdef DEBUGstralloc += a;
#endifdata = (char*)(memalloc(a)) + strrecsize;STR_LENGTH(data) = numchars;STR_REFCOUNT(data) = 1;data[numchars] = 0;
}
void string::_realloc(int numchars)
{if (numchars <= 0 || STR_LENGTH(data) <= 0){stringoverflow();}int a = quantize(numchars);int b = quantize(STR_LENGTH(data));if (a != b){
#ifdef DEBUGstralloc += a - b;
#endifdata = (char*)(memrealloc(data - strrecsize, a)) + strrecsize;}STR_LENGTH(data) = numchars;data[numchars] = 0;
}
void string::_free(int numchars)
{_freestrbuf(data);data = emptystr;
}
具体到细节里面有可以在框架接口common.h中加入内存处理的函数:
//
// memory management (undocumented)
// hides some BSD* incompatibility issues
//ptpublic void* ptdecl memalloc(uint a);
ptpublic void* ptdecl memrealloc(void* p, uint a);
ptpublic void ptdecl memfree(void* p);
ptpublic void ptdecl memerror();
ptpublic int ptdecl memquantize(int);ptpublic int __PFASTCALL pincrement(int* target);
ptpublic int __PFASTCALL pdecrement(int* target);
咱们用pmem.cpp去实现这里的函数
#include "stdio.h"
#include "stdlib.h"#include "common.h"// dynamic reallocation policy for strings and listsint ptdecl memquantize(int a)
{
……
}void* ptdecl memalloc(uint a)
{
……
}void ptdecl memerror()
{
……
}void* ptdecl memrealloc(void* p, uint a)
{
……
}void ptdecl memfree(void* p)
{
……
}
下来是string应该实现的操作:比如指派assgin函数
void assign(const char* sc, int initlen);
void assign(const char* sc);
void assign(char c);
void assign(const string& s);
这个函数只需要和构造函数和_alloc这些函数配合起来使用就行
下来是重载操作符:
string operator+ (const char* sc) const;
string operator+ (char c) const;
string operator+ (const string& s) const;bool operator== (const char* sc) const { return (strcmp(sc, data) == 0); }
bool operator== (char c) const;
bool operator== (const string& s) const;
bool operator!= (const char* sc) const { return !(*this == sc); }
bool operator!= (char c) const { return !(*this == c); }
bool operator!= (const string& s) const { return !(*this == s); }operator const char*() const { return data; }
[]操作符是,因为都需要进行条件判断,所以写成一个函数idx,进行长度的检查
void idx(int index) const { if(unsigned(index) >= unsigned(STR_LENGTH(data))) idxerror(); }char& operator[] (int i) { idx(i); return unique(*this)[i]; }
const char& operator[] (int i) const { idx(i); return data[i]; }
还有一类的操作符重载是友元函数类型的:
friend bool operator== (const char* sc, const string& s);
friend bool operator== (char c, const string& s);
friend bool operator!= (const char* sc, const string& s);
friend bool operator!= (char c, const string& s);
因为他的实现很简单,只是调用原来已经被重载的=号操作符
inline bool operator== (const char* sc, const string& s) { return s == sc; }
inline bool operator== (char c, const string& s) { return s == c; }
inline bool operator!= (const char* sc, const string& s) { return s != sc; }
inline bool operator!= (char c, const string& s) { return s != c; }
还有一类是需要导出的,所以前面跟上stdcall
ptpublic friend string operator+(const char* sc, const string& s);
ptpublic friend string operator+(char c, const string& s);
假如你看一下他的调用方式,你就应该知道他为何这么写了:
// test ptpublic friend string operator+(const char* sc, const string& s);
s2 = "str" + s1 + "ing";
// test ptpublic friend string operator+(char c, const string& s);
s2 = 's' + s1;
下来是类的友元函数,他们不需要进行外部调用,但是需要访问类的成员:
friend int length(const string& s);
friend int refcount(const string& s);
friend void clear(string& s);
friend char* ptdecl unique(string& s);
friend int pos(const string& s1, const string& s);
friend void assgin(string& s, const char* buf, int len);
这些可以写得很简单:
inline int length(const string& s) { return STR_LENGTH(s.data); }
inline int refcount(const string& s) { return STR_REFCOUNT(s.data); }
inline void assgin(string& s, const char* buf, int len) { s.assign(buf, len); }
inline void clear(string& s) { s.finalize(); }
inline bool isempty(const string& s) { return length(s) == 0; }
inline int pos(const string& s1, const string& s) { return pos(s1.data, s); }
下面的这些函数需要被外部调用,又需要访问成员变量的:
ptpublic friend int ptdecl pos(const char* s1, const string& s);
ptpublic friend int ptdecl pos(char s1, const string& s);
ptpublic friend int ptdecl rpos(char s1, const string& s);
ptpublic friend void ptdecl concat(string& s, const char* sc, int catlen);
ptpublic friend void ptdecl concat(string& s, const char c);
ptpublic friend void ptdecl concat(string& s, const string& s1);
ptpublic friend string ptdecl copy(const string& s, int from, int cnt);
ptpublic friend string ptdecl copy(const string& s, int from);
ptpublic friend char* ptdecl setlength(string& s, int newlen);
ptpublic friend void ptdecl del(string& s, int at, int cnt);
ptpublic friend void ptdecl del(string& s, int from);
ptpublic friend void ptdecl ins(const char* s1, int s1len, string& s, int at);
ptpublic friend void ptdecl ins(const char* s1, string& s, int at);
ptpublic friend void ptdecl ins(char s1, string& s, int at);
ptpublic friend void ptdecl ins(const string& s1, string& s, int at);
ptpublic friend bool ptdecl contains(const char* s1, int s1len, const string& s, int at);
ptpublic friend bool ptdecl contains(const char* s1, const string& s, int at);
ptpublic friend bool ptdecl contains(char s1, const string& s, int at);
ptpublic friend bool ptdecl contains(const string& s1, const string& s, int at);
咱们可以另外写一个pstrmanip.cpp去实现上面的函数,其实还可以把一些操作符重载也写在这里:
#include "stdlib.h"
#include "ptypes.h"string string::operator+ (const char* sc) const
{
}string string::operator+ (char c) const
{
}string string::operator+ (const string& s) const
{
}string operator+(const char* sc, const string& s)
{
}string operator+(char c, const string& s)
{
}bool string::operator== (char c) const
{
}bool string::operator== (const string& s) const
{
}int ptdecl pos(const char* sc, const string& s)
{
}int ptdecl pos(char c, const string& s)
{
}int ptdecl rpos(char c, const string& s)
{
}string ptdecl copy(const string& s, int from, int cnt)
{
}string ptdecl copy(const string& s, int from)
{
}void ptdecl del(string& s, int from, int cnt)
{
}void ptdecl del(string& s, int from)
{
}void ptdecl ins(const char* s1, int s1len, string& s, int at)
{
}void ptdecl ins(const char* s1, string& s, int at)
{
}void ptdecl ins(char s1, string& s, int at)
{
}void ptdecl ins(const string& s1, string& s, int at)
{
}bool ptdecl contains(const char* s1, int s1len, const string& s, int at)
{
}bool ptdecl contains(const char* s1, const string& s, int at)
{
}bool ptdecl contains(char s1, const string& s, int at)
{
}bool ptdecl contains(const string& s1, const string& s, int at)
{
}
这样整个类就被分开了,但是有个缺点。。用助手不好使了= =
转载于:https://www.cnblogs.com/jiangu66/p/3161401.html
一个简单的string类,读书看报系列(一)相关推荐
- C++ 一个简单的基类
继承 可在已有类的基础上添加功能 可给类添加数据 可修改类方法的行为 从一个类派生出另一个类时,原始类称为基类,继承类成为派生类 Webtown俱乐部决定跟踪乒乓球会员,设计一个简单的TableTen ...
- python简单代码演示效果-演示python如何创建和使用一个简单的元类的代码
在做工程闲暇时间,将做工程过程比较重要的一些内容备份一下,如下内容段是关于演示python如何创建和使用一个简单的元类的内容,应该能对小伙伴们也有用途. #!/usr/bin/env python # ...
- boost::mpi模块实现一个简单的点类,我们可以构建、添加、比较和 连载
boost::mpi模块实现一个简单的点类,我们可以构建.添加.比较和 连载 实现功能 C++实现代码 实现功能 (boost::mpi模块实现一个简单的点类,我们可以构建.添加.比较和 连载 C++ ...
- python自己做个定时器_技术图文:如何利用 Python 做一个简单的定时器类?
原标题:技术图文:如何利用 Python 做一个简单的定时器类? 背景 今天在B站上看有关 Python 最火的一个教学视频 -- "零基础入门学习 Python",这也是我们 P ...
- 在Kubernetes上部署一个简单的、类PaaS的平台,原来这么容易!
作者 | Bram Dingelstad 译者 | 弯月 责编 |徐威龙 封图| CSDN下载于视觉中国 我们都遇到过这种情况:有人发现了一个bug,然而这不是一般的软件bug,甚至都不是通常意义上的 ...
- 实验3.2 定义一个简单的Computer类
题目 定义一个简单的Computer类,有数据成员芯片(cpu).内存(ram).光驱(cdrom)等等,有两个公有成员函数run.stop.cpu为CPU类的一个对象,ram为RAM类的一个对象,c ...
- uniapp APP 端 WebSocket 使用,实现一个简单 WebSocket 工具类
背景 最近有需求要做一个简单业务的 APP 应用,简单考虑选用 uniapp + uview + vue2.x 方案,因为还有web端页面也需要用到 WebSocket ,简单封装了一个适应 web ...
- 技术图文:如何利用 Python 做一个简单的定时器类?
背景 今天在B站上看有关 Python 最火的一个教学视频,零基础入门学习 Python,这也是我们 Python基础刻意练习活动 的推荐视频教程. 在学习魔法方法的时候,有一节视频是制作一个简单的定 ...
- php-curl-class,一个简单PHP CURL类
这里要说明一下...这个类的形成是参考了晚上前辈们的代码加上我自己的理解见解而集成的...前辈们的代码出处已经忘记了 我在这里感谢这些前辈们给我的启发...希望这个类能给大家带来帮助...如果有不足的 ...
- [转贴]从零开始学C++之STL(二):实现一个简单容器模板类Vec(模仿VC6.0 中 vector 的实现、vector 的容量capacity 增长问题)...
首先,vector 在VC 2008 中的实现比较复杂,虽然vector 的声明跟VC6.0 是一致的,如下: C++ Code 1 2 template < class _Ty, cla ...
最新文章
- pl sql如何调试oracle存储过程,PL/SQL Developer中调试oracle的存储过程
- 几款LED灯带作为反向电流感应测试
- linux的tmp目录不会清空,关于Linux系统中/tmp目录的清除问题
- exe程序获得外部传入命令行方法
- 《python核心编程》读书笔记--第15章 正则表达式
- 关于更改apache和mysql的路径的问题..
- python怎么使用-如何使用 Python 开始建立
- [转]六种删除数据库重复行的方法
- 影视.20190507
- 超级简单的纯js 象棋,看一遍你也会写
- SecureCRT 经典配色方案
- 系统分析和设计方法之输出设计和原型化
- 20211高考成绩查询,青岛理工大学教务系统URP成绩查询、网上选课查分 http://211.64.192.21/,精英高考网...
- 读的, 且经过美化, 能在所有 JavaScript 环境中运行, 并且应该和对应手写的 JavaScript 一样快或者更快.
- 人工智能的历史与演变
- mysql bytes sent_MySQL服务器状态变量(mysqld)
- 软考网络工程师上午考试知识点总结整理
- 回归算法以及源码分享
- Python模糊基础点--文件操作
- 阿里云物联网平台设备模拟器