文档库 最新最全的文档下载
当前位置:文档库 › Immutable 模式与string 类的实现

Immutable 模式与string 类的实现

Immutable 模式与string 类的实现
Immutable 模式与string 类的实现

Immutable模式与string类的实现

撰文/透明

前言:在C++中要实现引用计数、共享内存的string类,对象的生存期管理是一个大问题。但是,使用Immutable模式之后,情况将得到大大改善。

梗概

禁止改变对象的状态,从而增加共享对象的坚固性、减少对象访问的错误,同时还避免了在多线程共享时进行同步的需要。

实现方法:在对象构造完成以后就完全禁止改变任何状态信息。如果需要改变状态,则生成一个状态与原对象不同的新对象。

场景

假设你正在为一家游戏公司开发一个和外太空、宇宙飞船有关的游戏,当然你有必要用某种方式来表示一艘宇宙飞船(不管它是属于地球人的还是属于外星人的)所处的位置。很自然的,你决定编写一个Position类。从一个Position对象应该可以查询到当前位置的x坐标和y坐标(我们的游戏比较简单,二维地图,呵呵),还应该可以根据输入的偏移量得到新的位置。很正确的设计,不是吗?(见例1)

例1:Position的设计

class Position{

private:

int x, y; //简单点,用整型数来表示坐标

public:

Position(int x, int y){ //ctor需要两个参数。

this->x = x;

this->y = y;

}

int getX( ){ return x; }

int getY( ){ return y; }

void Offset(int offX, int offY){ //根据偏移量得到新的位置

x+=offX;

y+=offY;

}

}

但是,如果我们的Position需要在多线程环境下使用,它能保证线程安全吗?答案是很明显的No!如果两条线程同时调用同一个Position对象的Offset函数,你就无法保证得到的结果是什么了。所以,为了保证线程安全,也许你还会想给Offset函数加上同步机制——麻烦了!

换个角度想想怎么样?假如我们根本不让Offset函数修改Position的内容?假如我们让Offset函数生成一个新的Position对象?如果是这样,Position对象就已经是线程安全的了——它没有任何“写”操作,而没有写操作的类是不需要同步的。于是我们这样做了,并且很轻松的得到了一个线程安全的Position类。(见例2)

例2:线程安全的Position类(这里只展示Offset函数)

Position Position::Offset(int offX, int offY){ //根据偏移量得到新的位置return Position(x+offX, y+offY);

}

约束

l 你有一个天性被动的类。这个类的实例不需要改变自己的状态。同时这个类的实例还被其他多个对象共享。

l 正确协调被共享的对象的状态改变非常困难。当一个对象的状态发生改变时,所有使用它的对象都应该得到通知。这造成了对象之间的紧耦合。

l 在多线程共享时,还需要使用同步机制来保证线程安全性。

解决方案

为了避免状态改变带来的诸多麻烦,不允许对实例的状态做任何修改。具体的做法就是:不在类的公开接口中出现任何可以修改对象状态的方法,只出现状态读取方法。如果client需要不同的状态,就生成一个新的对象。(见图1)

图1:Immutable模式的类图

效果

l 不再需要协调状态修改的代码,也不再需要协调任何同步代码。

l 生成了更多的对象。增加了对象生成和销毁的开销。

实现

Immutable模式的实现主要有以下两个要点:

1.除了构造函数之外,不应该有其它任何函数(至少是任何public函数)修改任何成员变量。

2.任何使成员变量获得新值的函数都应该将新的值保存在新的对象中,而保持原来的对象不被修改。

在“效果”中我已经讲到:Immutable模式会大大提高对象生成和销毁的频率。因此,在C++中实现Immutable模式时,还必须特别注意对象的生存周期。你可以尝试用智能指针[Meyers96, Item28]来帮助你处理对象的销毁问题,但是无论如何你都必须仔细检查以确保没有内存泄漏——如果每艘飞船的每次移动都会造成内存泄漏,你的游戏该是多么糟糕!

此外,Immutable模式还有一种变体:Read Only Object模式。它的做法是:当一个类的对象对于某些client可写、某些client不可写时,让这个类实现一个ReadOnly接口。然后让可写的client 直接访问对象,而让不可写的client通过ReadOnly接口访问该对象,从而实现了不同的读写权限控制。(如图2所示)

图2:Read Only Object模式

Immutable模式与string类的实现策略

如果你也读过[Meyers96],我想你一定对那个应用在String类上的COW(Copy-On-Write)策略[Meyers96, Item29]印象深刻。COW策略是“lazy evaluation”的发展形式。如果对String类的写操作数量很少,那么COW策略将大大提高整个String类的效率,并大大降低空间开销。

可是你知道吗?在STL中的string类并没有采用COW策略,从例3就可以看出这一点。为什么?为什么这么好的策略没有得到采用?相信你从[Meyers96]中便可发现:实际在String类上实现COW策略是如此复杂。更何况我们还必须考虑线程安全的问题。我完全有理由认为:正是因为考虑到这些复杂的情况,STL的实现者们才最终决定用一个比较低效但是安全的实现方案。

例3:STL中的string::operator=和string::operator[]

//下面代码出自SGI STL 2000年6月8日版本

//为了帮助读者理解,我做了些微改动,并在关键位置加上注释

//如果使用COW策略,operator=应该不做内容复制,而是进行引用计数

string& string::operator=(const string& s) {

if (&s != this)

assign(s.begin(),s.end()); // 这里的operator=只是简单的内容复制而已 return *this;

}

//如果使用COW策略,const的operator[]和非const的operator[]应该不同

//但是这里两个operator[]完全相同

const char & string::operator[](int n) const

{ return *(_M_start + n); } //_M_start是字符数组的起始位置

char & string::operator[](int n)

{ return *(_M_start + n); }

看到这些,我不能不开始猜想:为什么STL的设计者们一定要保留这些给他们造成麻烦的“修改函数”(即可以修改string内容的函数)?我想,这是因为他们希望让string的行为方式尽量接近于C语言的char *型字符串。不然,我真的想不出其他任何保留operator[]的理由。

那么,如果不必非要让string类的行为方式接近char *型字符串,如果string类的读操作应用频率远远大于写操作(在实际应用中这是很常见的),你会考虑如何实现一个string类?啊,也许你已经想到了:Immutable模式。你可以很舒服的使用[Meyers96]教你的引用计数方法来节约存储空间,你不必再担心写操作的同步问题或别的什么,因为已经没有写操作。任何改变字符串内容的操作都将得到一个新的string对象。而对象生存期管理和存储空间管理这两个大问题也因为Immutable模式的引入而大大简化,你完全可以参照[Meyers96]第183页到第189页的内容自己来解决它们。

代码示例

我用了一天的时间,做了一个简单的ImmutableString实现。其中实现细节用了Proxy类

[Meyers96],并参考了COM的引用计数规则[Pan99]。在这个例子中,读者可以感觉到:Immutable 模式大大简化了共享空间的字符串类型的实现,并为其中的一些方法(比如subString)的实现提供了非常大的便利。本来我想把代码放在文章里面,但是时间和空间受限,最后决定放弃。如果读者有兴趣,可以到下面URL去下载一份。

https://www.wendangku.net/doc/7f760729.html,/download/ImmutableString.zip

在该代码中,我做了一个简单的效率测试:反复进行字符串对象的赋值(operator=)操作。结果表明:ImmutableString的效率比std::string高出了一倍左右。假如你的业务就是不断的读取数据库、不断的赋值、不断的输出,而不对字符串进行修改,那么ImmutableString的效率提升是非常可观的。

该示例代码在VC .NET下编译通过。

相关模式

经常会使用Abstract Factory模式[GOF95]来创建新的对象。

大量的对象经常通过Flyweight模式[GOF95]被共享。

参考书目

[Meyers96] Scott Meyers, More Effective C++, Addison-Wesley, 1996.

[GOF95] Erich Gamma etc., Design Patterns: Elements of Reusable Object-Oriented Softwa re, Addison-Wesley, 1995.

中译本:《设计模式:可复用面向对象软件的基础》,李英军等译,机械工业出版社,

2000 年9 月。

[PAN99] 潘爱民,《COM原理与应用》,清华大学出版社,1999年11月。

C++string类型总结

对C++中string类型的总结 string类对象的构造 简化构造函数原型如下(注意,为了简便,把模板中最后一个默认参数省略了): 1: explicit basic_string(); 2: string(const char *s); 3: string(const char *s, size_type n); 4: string(const string& str); 5: string(const string& str, size_type pos, size_type n); 6: string(size_type n, E c); 7: string(const_iterator first, const_iterator last); string对象的操作 字符串比较 支持六种关系运算符(==、!=、>、>=、<、<=),其采用字典排序策略(与C中字符串比较策略完全一样)。这六个关系运算符是非成员的重载运算符。而这些 运算符都支持三种操作数组合:string op string、string op const char*、cons t char* op string(其中op是前面六种关系运算符中任意一种)。解释:提供运算 符的三种重载版本主要是从效率角度考虑的,其避免了临时string对象的产生。 另外,string类还提供了各种重载版本的成员函数compare来比较,简化函数原型为: 1: int compare(const string& str) const; 2: int compare(size_type p0, size_type n0, const string& str); 3: int compare(size_type p0, size_type n0, const string& str, si ze_type pos, size_type n); 4: int compare(const char* s) const; 5: int compare(size_type p0, size_type n0, const char* s) const; 6: int compare(size_type p0, size_type n0, const char* s, size_t ype n) const; 返回值:如果调用该函数的对象的比较序列小于操作数比较序列,则返回负数; 若相等,则返回0;否则,返回正数。

java String类的用法

1 String 类的用法 public class SetStringValue { /** * @param args */ public static void main(String[] args) { String str1=new String("Java是当今最流行的编程语言之一");//截取数组 String str2="java是优秀的技术"; char[] szStr={'H','e','l','l','o',',','j','a','v','a'}; String str3=String.copyValueOf(szStr);//复制数组,所有数组。 String str4=String.copyValueOf(szStr,6,4);//所取数组,开始位置,所取个数 System.out.println(str1); System.out.println(str2); System.out.println(str3); System.out.println(str4); // TODO Auto-generated method stub } } 2 public class StringPool { /** * @param args */ public static void main(String[] args) { String str1="Good!"; String str2="Good!"; String str3=new String("Good!"); if(str1==str2)//判断地址是否相同 { System.out.println("str1=str2");//地址相同则输出相等

JAVA实验报告四(实现String类)

JA V A实验报告实验四运用JavaFx实现时钟动画 班级:计算机科学与技术1306 学号: 00 姓名:王雨思 指导教师:鲁鸣鸣 2014 年 12 月 1 日

目录 一.概述 (6) 二.总体方案设计 (7) 三.详细设计 (8) 四.程序的调试与运行结果说明 (9) 五.课程设计总结 (10) 六.后记 (11) 七.附录 (12) 参考文献 (13)

一概述 1.课程设计的目的 了解和掌握String类的实现原理 2.课程设计的要求 基于ArrayList实现可以深度复制(Deep Copy)的栈结构。1.首先用ArrayList实现栈结构 2.接着将第1步实现的栈通过Clonable接口实现深度复制 3.课程设计的主要设计思想 基于ArrayList实现可以深度复制(Deep Copy)的栈结构。二总体方案设计 编写程序实现MyString类的下列操作: public MyString(char[] chars); public char charAt(int index); public int length(); public MyString substring(int begin, int end); public MyString toLowerCase(); public boolean equals(MyString s); public static MyString valueOf(int i); public int compare(String s); public MyString substring(int begin); public MyString toUpperCase(); public char[] toChars();

STRING类函数用法总结3

C++中的string类 前言:string的角色 1string使用 1.1充分使用string操作符 1.2眼花缭乱的string find函数 1.3string insert,replace,erase2string和C风格字符串 3string和Charactor Traits 4string建议 5小结 6附录前言:string的角色 C++语言是个十分优秀的语言,但优秀并不表示完美。还是有许多人不愿意使用C或者C++,为什么?原因众多,其中之一就是C/C++的文本处理功能太麻烦,用起来很不方便。以前没有接触过其他语言时,每当别人这么说,我总是不屑一顾,认为他们根本就没有领会C++的精华,或者不太懂C++,现在我接触perl,php,和Shell脚本以后,开始理解了以前为什么有人说C++文本处理不方便了。 举例来说,如果文本格式是:用户名电话号码,文件名name.txt Tom23245332 Jenny22231231 Heny22183942 Tom23245332 ... 现在我们需要对用户名排序,且只输出不同的姓名。 那么在shell编程中,可以这样用: awk'{print$1}'name.txt|sort|uniq 简单吧? 如果使用C/C++就麻烦了,他需要做以下工作: 先打开文件,检测文件是否打开,如果失败,则退出。 声明一个足够大得二维字符数组或者一个字符指针数组 读入一行到字符空间 然后分析一行的结构,找到空格,存入字符数组中。 关闭文件 写一个排序函数,或者使用写一个比较函数,使用qsort排序 遍历数组,比较是否有相同的,如果有,则要删除,copy... 输出信息 你可以用C++或者C语言去实现这个流程。如果一个人的主要工作就是处理这种

编写strcpy函数和类String的构造函数、析构函数、赋值函数和重载运算符函数

编写strcpy函数和类String的构造函数、析构函数、赋值函数和重载运算符函数 已知strcpy函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中strDest是目的字符串,strSrc是源字符串。 (1)不调用C++/C的字符串库函数,请编写函数strcpy char *strcpy(char *strDest, const char *strSrc); //将源字符串加const,表明其为输入参数 { assert((strDest!=NULL) && (strSrc !=NULL)); // 2分 //对源地址和目的地址加非0断言 char *address = strDest; // 2分//为了实现链式操作,将目的地址返回 while( (*strDest++ = * strSrc++) != …\0? ) // 2分 NULL ; return address ; // 2分 } (2)strcpy能把strSrc的内容复制到strDest,为什么还要char * 类型的返回值? 答:为了实现链式表达式。// 2分 例如int length = strlen( strcpy( strDest, “hello world”) ); 二、网上广泛流传的,也是摘自林锐的 http://www.blog.sh/user3/skyflowing/archives/2006/60452.html 题目: 已知strcpy函数的原型是: char * strcpy(char * strDest,const char * strSrc); 1.不调用库函数,实现strcpy函数。 2.解释为什么要返回char *。

string类的使用教程

这个是string类的使用教程,可以参考一下 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用= 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。 好了,进入正题……… 首先,为了在我们的程序中使用string类型,我们必须包含头文件。如下:#include //注意这里不是string.h string.h是C字符串头文件 1.声明一个C++字符串 声明一个字符串变量很简单: string Str; 这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String类的构造函数和析构函数如下: a) string s; //生成一个空字符串s b) string s(str) //拷贝构造函数生成str的复制品 c) string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值 d) string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值 e) string s(cstr) //将C字符串作为s的初值 f) string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s 的初值。 g) string s(num,c) //生成一个字符串,包含num个c字符 h) string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值 i) s.~string() //销毁所有字符,释放内存 都很简单,我就不解释了。 2.字符串操作函数 这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。 a) =,assign() //赋以新值 b) swap() //交换两个字符串的内容 c) +=,append(),push_back() //在尾部添加字符 d) insert() //插入字符 e) erase() //删除字符 f) clear() //删除全部字符 g) replace() //替换字符 h) + //串联字符串 i) ==,!=,<,<=,>,>=,compare() //比较字符串 j) size(),length() //返回字符数量

java对象转换String类型的三种方法

北大青鸟中关村 java对象转换String类型的三种方法在很多情况下我们都需要将一个对象转换为String类型。一般来说有三种方法可以实现:Object.toString()、(String)Object、String.valueOf(Object)。下面对这三种方法一一分析 一、采用Object.toString() toString方法是https://www.wendangku.net/doc/7f760729.html,ng.Object对象的一个public方法。在java中任何对象都会继承Object 对象,所以一般来说任何对象都可以调用toString这个方法。这是采用该种方法时,常派生类会覆盖Object里的toString()方法。 但是在使用该方法时要注意,必须保证Object不是null值,否则将抛出NullPointerException 异常。 二、采用(String)Object 该方法是一个标准的类型转换的方法,可以将Object转换为String。但是在使用该方法是要注意的是需要转换的类型必须是能够转换为String的,否则会出现CalssCastException异常错误。 代码代码如下: Object o = new Integer(100); String string = (String)o; 这段程序代码会出现https://www.wendangku.net/doc/7f760729.html,ng.ClassCastException: https://www.wendangku.net/doc/7f760729.html,ng.Integer cannot be cast to https://www.wendangku.net/doc/7f760729.html,ng.String。因为将Integer类型强制转换为String类型,无法通过。 三、String.valueOf(Object) 上面我们使用Object.toString()方法时需要担心null问题。但是使用该方法无需担心null值问题。因为在使用String.valueOf(Object)时,它会判断Object是否为空值,如果是,则返回null。下面为String.valueOf(Object)的源码: 代码代码如下: public static String valueOf(Object obj) { return (obj == null) ? "null" : obj.toString(); } 从上面我们可以看出两点:一是不需要担心null问题。二是它是以toString()方法为基础的。但是一定要注意:当object为null时,String.valueOf(object)的值是字符串对象:"null",而不是null!!!

string类中函数介绍

标准c++中string类函数介绍 注意不是CString 之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用= 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。 好了,进入正题……… 首先,为了在我们的程序中使用string类型,我们必须包含头文件。 如下: #include //注意这里不是string.h string.h是C字符串头文件 #include using namespace std; 1.声明一个C++字符串 声明一个字符串变量很简单: string Str; 这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str 初始化为一个空字符串。String类的构造函数和析构函数如下: a) string s; //生成一个空字符串s b) string s(str) //拷贝构造函数生成str的复制品 c) string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值 d) string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多strlen”的部分作为字符串的初值 e) string s(cstr) //将C字符串作为s的初值 f) string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。 g) string s(num,c) //生成一个字符串,包含num个c字符 h) string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值 i) s.~string() //销毁所有字符,释放内存 都很简单,我就不解释了。 2.字符串操作函数 这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。 a) =,assign() //赋以新值 b) swap() //交换两个字符串的内容 c) +=,append(),push_back() //在尾部添加字符

【实验5】c++MyString类实现

ccnu_hupo_cpp_class_tst6exercise2_by:lele_2013_10_30 new不忘delete Design the string class in the C++ library by providing your own implementation for the following functions (name your class MyString): MyString();//构造 MyString(const char* cString);//地址不能变 char at(int index) const;//输入数组下标,返回字符 int length() const;//长度 void clear();//清空len=0 bool empty() const;//是否清空?len不变 int compare(const MyString& s) const;// int compare(int index, int n, const MyString& s) const; void copy(char s[], int index, int n); char* data() const; int find(char ch) const; int find(char ch, int index) const; int find(const MyString& s, int index) const; */ #include #include using namespace std; class MyString { public: MyString(); MyString(const char* cString); char at(int index) const;// int length() const; void clear(); bool empty() const; int compare(const MyString& s) const; int compare(int index, int n, const MyString& s) const; void copy(char s[], int index, int n); char* data() const; int find(char ch) const; int find(char ch, int index) const; int find(const MyString& s, int index) const; ~MyString()

在C++中自定义string类

在C++中自定义string类 #pragma once #include class str { public: str(void); str(char*); ~str(void); protected: char* string; public: int length(void); int findchar(char s); int findstr(char* str); char** seg(char* sign, int* out=NULL); char* copy(int start, int end); int findchar(char* str, char c); int findstr(char* str, char* s); int contain(char* str); int contain(char* strin, char* str); int length(char* p); char* copy(char* str, int start, int end); char** seg(char* str, char* sign, int* out=NULL); char* tochar(void); char* tochar(str str); void tostring(char* c); char* substr(char* string, char* str); bool substr(char* str); char* suballstr(char* string, char* str); bool suballstr(char* str); char* appendstr(char* string, char* str); bool appendstr(char* str); };

各个类及其方法的实现

客户端:(六个类) ChatClient、Denglu、Hall、HUIQICC 、Panecc、Registry 功能: 1、ChatClient: * 该类主要关于客户端与服务器之间的通信,包括聊天信息、悔棋信息、认输信息、退出信息、注册信息、登陆信息等等* 通过该类还调用了大量的Panecc类的方法,实现通信信息在界面上的实现 * * 主要方法是Connect(),通过调用该方法建立与服务器端的连接,在该方法里,new了一个Thread对象, * 同时架设了经过初步包装基本的管道(DataInputStream和DataOutputStream)。接下来便开始接收服务器端 * 发来的消息了,通过简单的协议,实现不同种类消息的接收和解析,该协议便是一串数字(int类型), * 在发送消息方法里先写进一串数字,再写入需要发送的消息内容。同理,接收消息时先读取数字,再根据不同的数字 * 解析出不同的消息种类。 * 除了Connect()方法之外,还有很多信息的发送方法,比如

聊天信息(SendMessage(String message))、登陆信息(SendLogin(String name,String key)) * 、注册信息(SendZhuce(String name,String pass))、发送猜先信息(sendcai(int a))等等 2、Denglu: * 该类是客户端的主驱动类,在该类中声明并初始化了ChatClient类的对象cc, * 并通过该对象调用了ChatClient类的许多方法; * 该类主要是关于登陆界面,并实现了相关监听; * 该类还存在一个内部类--paneLogin ,这个内部类主要是画界面,监听功能在主类中实现 * * 通过该类,将用户信息,发送给服务器,再由服务器连接数据库,判断登陆的相关信息。 3、Hall: * 该类是关于登陆大厅,存在一个内部类--hallt,该内部类

C++课程设计String类

#include #include #include #include #define Base 10000 #define M 1000 /*初始长度为Base,以后依次增加M*/ using namespace std; class String { private: char *str; ///str为指针,len为长度,size为能容纳的最大字符数 int len,size; public: ///构造函数,能直接确定长度,或者用一个字符串初始化 String (int maxsize=Base); String (const char *s); char *c_str() { return str; } ///返回一个指向字符串头部的C语言的指针String insert(int pos,const char c); ///在pos位置插入字符c String insert(int pos,String s); ///在pos位置插入String s String insert(int pos,const char *s); ///插入字符串 String Delete(int pos); ///删除pos位置的字符 String Delete(int start,int end); ///删除区间内的字符 String Delete(char c); ///删除所有的c字符 int copy(char *s,int num,int start); ///从start开始复制num个字符到str中 int search(char c); ///返回第一个出现字符c的位置 char operator [] (int pos); String operator = (String other) ; ///重载= 运算符 String operator = (const char * other) ; ///还是重载,使其支持字符串直接赋值 String operator + (String &other) const; ///重载,返回两个字符串连接 String operator += (String &other) ; ///还是重载,在原String后添加String bool operator < ( String &other) ; ///重载< ,比较大小 ///用重载好了的< ,直接定义其他运算符 bool operator > ( String &other) { return other < *this;} bool operator >= ( String &other) { return !(*this < other);} bool operator <= ( String &other) { return !(other < *this);} bool operator == ( String &other) { return (other <= *this) && (*this <= other);} bool operator != ( String &other) { return other < *this || *this < other;}

Qt 的QString类的使用

Qt 的QString类的使用Qt的QString类提供了很方便的对字符串操作的接口。 1.使某个字符填满字符串,也就是说字符串里的所有字符都有等长度的ch来代替。 QString::fill ( QChar ch, int size = -1 ) 例: QString str = "Berlin"; str.fill('z'); // str == "zzzzzz" str.fill('A', 2); // str == "AA" 2,从字符串里查找相同的某个字符串str。 int QString::indexOf ( const QString & str, int from = 0, Qt::CaseSensitivity cs = Qt::CaseSensitive ) const 例如: QString x = "sticky question"; QString y = "sti"; x.indexOf(y); // returns 0 x.indexOf(y, 1); // returns 10 x.indexOf(y, 10); // returns 10 x.indexOf(y, 11); // returns -1 3指定位置插入字符串 QString & QString::insert ( int position, const QString & str ) 例如: QString str = "Meal"; str.insert(1, QString("ontr")); // str == "Montreal" 3,判断字符串是否为空。 bool QString::isEmpty () const 如: QString().isEmpty(); // returns true QString("").isEmpty(); // returns true QString("x").isEmpty(); // returns false QString("abc").isEmpty(); // returns false

String类的基本特点

1、课程名称:String类的基本特点 2、知识点 2.1、上次课程的主要知识点 数组 2.2、本次预计讲解的知识点 1、String类的两种实例化方式的区别; 2、String类对象的比较; 3、String类对象的使用分析。 3、具体内容(★★★★★) 3.1、String类的两种实例化方式 String并不是一个基本数据类型,它本身属于一个类,但是这个类在设计的过程之中加入了一些Java自己的特殊支持,

所以对于这个类的对象实例化方式就有两种形式: ·直接赋值:String 对象= "内容" ; ·构造方法:public String(String s)。 范例:使用直接赋值 范例:利用构造方法 至少现在通过执行结果来讲,String类的两种实例化方式都是可用的。 3.2、String的相等比较 如果说现在有两个int型的变量,那么要进行相等的判断,则直接使用“==”即可。 范例:两个int比较 发现两个利用直接赋值实现的程序,那么使用“==”的时候可以正常的进行相等判断。 但是如果现在将同样的操作形式用在String上呢? 范例:观察String的比较

通过现在的执行可以发现一个非常严重的问题,此时字符串的内容实际上都是相同的,而在使用“==”比较之后发现有比较结果是false,那么为什么呢? 所以发现在程序中如果使用“==”比较的只是两个对象(任意的引用类型)堆内存地址数值,属于数值内容的比较,并不是堆内存中保存内容的比较,那么要想进行String对象内容的比较则可以利用String类中提供的一个方法完成:·字符串比较(暂时将此方法进行修改):public boolean equals(String str)。 范例:利用equals()实现字符串内容的比较 由于内容是可控的因素,而地址是不可控的因素,所以在日后的开发之中,只要是字符串的比较都使用equals()方法完成,绝对不可能出现“==”。 面试题:请解释在String比较中“==”与“equals()”的区别? ·“==”:是Java本身提供的关系运算符,可以进行数值比较,如果用在String上表示对象内存地址数值比较; ·“equals()”:是String类自己定义的方法,用于进行字符串内容的比较。 3.3、String匿名对象 任何的编程语言都不会提供有字符串这一数据类型。字符串的描述在很多语言之中都使用字符数组表示。而在Java 的设计之处为了解决这样的问题,专门提供了一个String类来进行描述。但是随着发展,为了能够让程序变得更加的易于开发,所以在Java里面也提供双引号声明的数据,而这些数据,在Java中并不是普通的变量,而是属于String类的匿名

ANSI字符串类String的实现及使用

ANSI字符串类String的实现及使用 和C#不一样,C和C++的内部都没有字符串数据类型,但是我们可以用C++建立一个实现字符串相关操作的类型:String 下面的程序分成两个部分: (1)String类:类头String.h和类实现String.cpp (2)String类使用演示程序Main.cpp 类头文件String.h代码如下: #ifndef STRING_H #define STRING_H #include using namespace std; class String { friend ostream & operator< friend istream & operator>>(istream & input, String & s); public: String(const char* = ""); String(const String &); ~String(); const String & operator=(const String &); //赋值 String & operator+=(const String &); //字符串连接 int operator!() const; //String为空? int operator==(const String &) const; //测试s1==s2 int operator!=(const String &) const; //测试s1!=s2 int operator(const String &) const; //测试s1>s2 int operator<=(const String &) const; //测试s1<=s2

C++ 中的STRING类 的各种操作说明

之所以抛弃char*的字符串而选用C++标准程序库中的string类,是因为他和前者比较起来,不必 担心内存是否足够、字符串长度等等,而且作为一个类出现,他集成的操作函数足以完成我们大多数情况下(甚至是100%)的需要。我们可以用 = 进行赋值操作,== 进行比较,+ 做串联(是不是很简单?)。我们尽可以把它看成是C++的基本数据类型。 首先,为了在我们的程序中使用string类型,我们必须包含头文件 。如下: #include //注意这里不是string.h string.h是C字符串头文件 1.声明一个C++字符串 声明一个字符串变量很简单: string Str; 这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str初始化为一个空字符串。String 类的构造函数和析构函数如下: a) string s; //生成一个空字符串s b) string s(str) //拷贝构造函数生成str的复制品 c) string s(str,stridx) //将字符串str内"始于位置stridx"的部分当作字符串的初值 d) string s(str,stridx,strlen) //将字符串str内"始于stridx且长度顶多strlen"的部分作为字符串的初值 e) string s(cstr) //将C字符串作为s的初值 f) string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。 g) string s(num,c) //生成一个字符串,包含num个c字符 h) string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值 i) s.~string() //销毁所有字符,释放内存 都很简单,我就不解释了。 2.字符串操作函数 这里是C++字符串的重点,我先把各种操作函数罗列出来,不喜欢把所有函数都看完的人可以在这里找自己喜欢的函数,再到后面看他的详细解释。 a) =,assign() //赋以新值 b) swap() //交换两个字符串的内容 c) +=,append(),push_back() //在尾部添加字符 d) insert() //插入字符 e) erase() //删除字符 f) clear() //删除全部字符 g) replace() //替换字符 h) + //串联字符串 i) ==,!=,<,<=,>,>=,compare() //比较字符串 j) size(),length() //返回字符数量 k) max_size() //返回字符的可能最大个数 l) empty() //判断字符串是否为空 m) capacity() //返回重新分配之前的字符容量 n) reserve() //保留一定量内存以容纳一定数量的字符 o) [ ], at() //存取单一字符

表达式类型的实现毕业设计(论文)(已处理)

表达式类型的实现毕业设计(论文)(已处理)课程设计表达式类型的实现 学院计算机学院专业计算机科学与技术年级班别 2006级01班学号3106006394 学生姓名方锐洲辅导教师__ 吴伟民_______ 成绩_______ ______ 2008年7月 3 日 表达式类型的实现 目录 一需求分析 二概要设计 1数据类型的声明 2表达式的抽象数据类型定义 3整体设计 三详细设计 1二叉树的存储类型 2顺序栈的存储类型 3表达式的基本操作 4主程序和其他伪码算法 5函数的调用关系 四设计和调试分析 五用户手册 六测试 七课程设计的心得和心得以及问题-----18

八参考文献 九附录程序清单 一需求分析课程设计要求 问题的描述 一个表达式和一棵二叉树之间存在着自然的对应关系写一个程序实现 基于二叉树表示的算术表达式Expression的操作 基本要求 一必做部分 假设算术表达式Expression内可以含有变量a-z常量0-9和二元运算 符-乘幂实现以下操作 1ReadExpr E ――以字符序列的形式输入语法正确的前缀表达式并构造 表达式E 2WriteExpr E ――用带括号的中缀表达式输出表达式E 3Assign Vc ――实现对变量V的赋值V c变量的初值为0 4Value E ――对算术表达式E求值 5CompoundExpr pE1E2 ――构造一个新的复合表达式E1pE2 二选做部分 1以表达式的原书写形式输入支持大于0的正整数常量 2增加常数合并操作MergeConst E 合并表达式E中所有常数运算例如对表 达式E 23-a b34 进行合并常数的操作后求得E 5-a b12 测试数据 分别输入0a-91abc5x28x32x2x6并输出 每当输入一个表达式后对其中的变量赋值然后对表达式求值还有很多测试的数据详细请见附上的文件Testtxt 二概要设计 1数据类型的声明

字符串类的设计与实现

C++ 上机实验报告 上机实验名称:类与对象 实验题目:字符串类的设计与实现 班级: 学号: 姓名: 指导教师:张荣博

一.实验目的: 1.掌握C++类的概念和基本组成,学会设计类,掌握类的使用方法。 2.了解类的各成员在类中的封装特性。 3.熟悉各种成员函数包括构造、析构及内联等函数的定义与使用。 二.字符串UML图 String -*m_data : char +String (*str : const char = NULL) :String +~ String() : String +String(&other :const String ) :String +length(*str : char) :int +& operator =( &other : const String) : String + print() : void +comparestr(*str1 :const char ,*str2 : const char) : int +stringlianjie(*str1 : char,*str2 : char) : void 三.调试过程 1.实验前先查阅相关书籍,了解学习关于字符串的内容。理解本次实验目的,与同组的成员交流。 2.实验时,增加了一些对两个字符串的处理,处理字符串的比较时,对比较的方法有不会的,向老师及同组的同学请教,使用比较ASCII码比较。 3.实验后,进一步学习UML图。 四.测试结果 1.输入一个字符串 2..输出对这个字符串的操作

3..输入两个字符串 4..输出对这两个字符串的处理 五.程序代码: #include #include #include #include using namespace std; class String { public: String(const char *str = NULL); String(const String &other);

C++中的string常用函数用法总结

C++中的string常用函数用法总结首先,为了在我们的程序中使用string类型,我们必须包含头文件。 如下: #include //注意这里不是string.h string.h是C字符串头文件 #include using namespace std; 1.声明一个C++字符串 声明一个字符串变量很简单: string Str; 这样我们就声明了一个字符串变量,但既然是一个类,就有构造函数和析构函数。上面的声明没有传入参数,所以就直接使用了string的默认的构造函数,这个函数所作的就是把Str 初始化为一个空字符串。String类的构造函数和析构函数如下: a) string s; //生成一个空字符串s b) string s(str) //拷贝构造函数生成str的复制品 c) string s(str,stridx) //将字符串str内“始于位置stridx”的部分当作字符串的初值 d) string s(str,stridx,strlen) //将字符串str内“始于stridx且长度顶多st rlen”的部分作为字符串的初值 e) string s(cstr) //将C字符串作为s的初值 f) string s(chars,chars_len) //将C字符串前chars_len个字符作为字符串s的初值。 g) string s(num,c) //生成一个字符串,包含num个c字符 h) string s(beg,end) //以区间beg;end(不包含end)内的字符作为字符串s的初值 i) s.~string() //销毁所有字符,释放内存 都很简单,我就不解释了。

相关文档
相关文档 最新文档