对于这个类,写过程序的都知道应该含有的方法是

初始化、销毁、拼接、求长度、清除、判断是否为空等、还有一些操作符重载

一、先看初始化:

可以想到应该有默认构造的的、带有字符串的、带有默认字符的、还有一个拷贝构造函数

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 DEBUG
stralloc += a;
#endif
data = (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 DEBUG
stralloc += a - b;
#endif
data = (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 lists int 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)
{
}

这样整个类就被分开了,但是有个缺点。。用助手不好使了= =

一个简单的string类,读书看报系列(一)的更多相关文章

  1. C++定义一个简单的Computer类

    /*定义一个简单的Computer类 有数据成员芯片(cpu).内存(ram).光驱(cdrom)等等, 有两个公有成员函数run.stop.cpu为CPU类的一个对象, ram为RAM类的一个对象, ...

  2. VC++ 一个简单的Log类

    在软件开发中,为程序建立Log日志是很必要的,它可以记录程序运行的状态以及出错信息,方便维护和调试. 下面实现了一个简单的Log类,使用非常简单,仅供参考. // CLogHelper.h : hea ...

  3. python+selenium之自定义封装一个简单的Log类

    python+selenium之自定义封装一个简单的Log类 一. 问题分析: 我们需要封装一个简单的日志类,主要有以下内容: 1. 生成的日志文件格式是 年月日时分秒.log 2. 生成的xxx.l ...

  4. Python之自定义封装一个简单的Log类

    参考:http://www.jb51.net/article/42626.htm 参考:http://blog.csdn.net/u011541946/article/details/70198676 ...

  5. Python+Selenium中级篇之8-Python自定义封装一个简单的Log类《转载》

    Python+Selenium中级篇之8-Python自定义封装一个简单的Log类: https://blog.csdn.net/u011541946/article/details/70198676

  6. 自己实现简单的string类

    1.前言 最近看了下<C++Primer>,觉得受益匪浅.不过纸上得来终觉浅,觉知此事须躬行.今天看了类类型,书中简单实现了String类,自己以前也学过C++,不过说来惭愧,以前都是用C ...

  7. 实现简单的string类

    摘要 实现了一个string类,包括基本的构造.赋值.判断.大小写等. String API Constructors string(); string(const char& ch); st ...

  8. [转贴]从零开始学C++之STL(二):实现一个简单容器模板类Vec(模仿VC6.0 中 vector 的实现、vector 的容量capacity 增长问题)

    首先,vector 在VC 2008 中的实现比较复杂,虽然vector 的声明跟VC6.0 是一致的,如下:  C++ Code  1 2   template < class _Ty, cl ...

  9. 自己写的一个简单的Tab类

    //------------- PS_DOM 功能函数 start----------------var PS_DOM ={ indexOf: function(arr, e){ for(var i= ...

随机推荐

  1. 在asp.net页面上按回车会触发Imagebutton控件的Click事件

    原文:在asp.net页面上按回车会触发Imagebutton控件的Click事件 问题: 用asp.net做的aspx页面,无论是否有文本框.下拉框.复选框……获得焦点,只要在当前页面上按一下回车就 ...

  2. 对web.config的ConnectionString加密

    原文:对web.config的ConnectionString加密 本文参考了wayshan的博客,原文地址:http://www.cnblogs.com/wayshan/archive/2012/0 ...

  3. UC编程:输入输出重定向(系统调用)

    在Unix下,系统重定向是使用dup和dup2函数完成的 在学习使用这两个函数之前,必须要搞懂一个概念就是文件描述符 摘自:<文件描述符和文件指针的区别> 文件描述符就是open文件时产生 ...

  4. openwrt路由器更换了Flash之后需要修改的源码

    假如我使用的是WR703N,改为8M内存: 1 修改openwrt/target/linux/ar71xx/image/Makefile文件 $(eval $(call SingleProfile,T ...

  5. JQuery在Ajax的Post提交中国乱码的解决方案

    介绍: 在JQuery的Ajax POST要求,一个要求.中国的背景之中,乱码,如何解决呢? 问题简介: var regid = $('#oregion').combobox('getValue'); ...

  6. 1001. 杀死吸引力(3n+1)猜想 (15)(ZJUPAT 数学)

    主题链接:http://pat.zju.edu.cn/contests/pat-b-practise/1001 卡拉兹(Callatz)猜想: 对不论什么一个自然数n,假设它是偶数,那么把它砍掉一半. ...

  7. Apple Swift中英文开发资源

    Apple Swift中英文开发资源集锦[apple swift resources] 找到的一些Apple Swift中英文资源原文链接,希望对大家有所帮助.欢迎大家补充,原始资源链接最好! The ...

  8. JavaScript精彩范例(1)——Jquery EasyUI应用的一个框架实例

    从网上看到的,非常漂亮,放在这里和大家分享一下,作者是疯狂秀才 这是截图 >>这是下载地址<<

  9. iOS生命周期 & 通知中心

    笔记内容 学习笔记-段玉磊 Stanford course View Controller Lifecycle 这篇文是我记载Developing iOS 7 Apps公开课 第5课的笔记 UITex ...

  10. JAVA学习:多态

    多态:可以理解为事物存在的多种体现形态.   人:男人,女人 动物:猫,狗. 猫 x = new 猫(); 动物 x = new 猫()   1,多态的体现 父类的引用指向了自己的子类对象. 父类的引 ...