Ansistring使用方法大全 2

来源:互联网 发布:粉笔上的数据如何重置 编辑:程序博客网 时间:2024/05/29 19:46

第一个是缺省构造函数,就是生命一个AnsiString的时候使用的,比如

代码:
AnsiString Str1;

第二个是将字符串常量或者字符数组或者字符指针转换成AnsiString的构造函数,他是根据C字符串的规则进行构造,即以第一个遇到的'\0'字符作为结束字符的。常见的应用是
代码:
AnsiString Str2 = "TestString";

第三个是标准的拷贝构造函数,当执行一个赋值操作的时候实际上就是使用了这个构造函数。
第四个是指定了长度和源的构造函数,他和第二个不同的是,不是以'\0'字符作为结束字符的,而是按照指定的长度为准,这个构造函数可以突破C语言中字符串的限制和不足,可能在实际中更具使用价值,大多数的API返回的都是char*,但并不一定都是可视的字符,也可能包含了'\0',就可以使用这个构造函数来实现对内容的拷贝,尽管第二个参数是unisgned char类型,但是实际中使用好像可以突破256的限制,在一定意义上将这个构造函数可以是我们在使用BCB的时候避免使用new来分配char类型的数组数据,在一个局部的应用中,使用AnsiString保存临时的char数组数据,不需要考虑在什么异常的情况下需要释放内存,因为超出作用域的时候,AnsiString是可以自己释放的。

第五个构造函数可以是的AnsiString可以直接和wchar_t*进行转换,就是可以直接将w_chart*使用=赋值给AnsiString类型。

第六个是将整型转换为字符串的构造函数,也就是可以直接将一个int类型的值赋给AnsiString,其结果和通过IntToStr赋值一样的。
如:
代码:
int Temp = 46573284;
AnsiString Str3 = IntToStr(Temp); 和
AnsiString Str4 = Temp;

结果是一样的。

第七个至第十五个和第六个类似,作用也相当。

第十六个是将Windows的WideString转换为AnsiString的构造函数,也就是可以直接将WideString赋值给AnsiString,而不需要使用其他的方法或者API进行转换,功能和AnsiString(wchar_t*)类似。

String和string是不同的,string是标准从c++支持的处理字符串的类,在c++里我们经常这样使用string
代码:

cout<

但我们不能直接把String像这样使用,但String其实重载了<<这个操作符,如果要这样使用我们必须在头部加入:
#define VCL_IOSTREAM

这样我们可以这样了:
代码:

String str="hello world";
cout<

同理,我们还可以这样:
代码:

String str;
cin>>str;

在使用stl的时候,我们经常需要string,但String没有提供直接转换为string的方法,但我们可以这样:
代码:

//---------------------------------------------------------------------------

#pragma hdrstop
#include
#include
#define VCL_IOSTREAM
#include

//---------------------------------------------------------------------------
using namespace std;
#pragma argsused
int main(int argc, char* argv[])
{
  String str="hello world";
  string ss(str.c_str());

  cout<  system("pause");
  return 0;
}

这时我们可以使用stl的强大能力来处理String了。

混用AnsiString和c_str()的安全问题by nethobo

  当你使用返回AnsiString类型变量的函数,当你要写一个返回AnsiString变量
(不是指针也不是引用)函数时,或者当你使用一个以AnsiString变量为参数的函数,
或者当你整天用VCL控件传入传出AnsiString属性变量时,当这个AnsiString变量
包含很长一个字符串时,你是否有些担心有些不安?担心对象的构造与析构,更担心
的是大字符串的复制(分配内存、内存复制、删除内存)所带来的效率问题?如果你
是一个完美主义者或者是一个比较负责的程序作者比较关系程序效率的话,我想你一
定在每次使用时都有与我一样的这种不安的感觉。
  另外当你想要对一个AnsiString变量所含的字符串进行c的char*裸字符串操作时,
你用AnsiString::c_str()获得char*的指针然后对其进行c字符串操作,这时你是否
会担心你所作的是否会与AnsiString冲突呢,当然前提是你不想一上来就用strcpy
自己作一拷贝(还是效率问题)。

  下面我就本人近来几天编程中发现的问题来探讨一下AnsiString的效率问题及
其c_str()的安全问题。

  BCB的提供了操作动态字符串的类AnsiString的unicode版的WideString,
而且在VCL类中凡用到字符串类型时都是使用的AnsiString。但有时用
c的char*裸字符串来处理一些问题更方便,尤其是在一些编码与解码算法中。
为此AnsiString提供了c_str()函数以返回其内部的char*指针供使用(WideString
中为c_bstr(),问题类似,以下只以AnsiString和c_str为例)。
  首先我们看看第二个问题(它和第一个问题直接相关),看下面的代码:

AnsiString src="test AnsiString";
AnsiString strTest=src; //拷贝构造
char* cp=strTest.c_str();
cp[0]='T';

运行完后,strTest和src的值是什么呢?结果可能与你所预想的大不相同,两都的值都
变成了"Test AnsiString"!也就是说cp[0]='T'的操作同时改变了两个AnsiString变量
的值。为什么会这样呢,执行时按下Ctrl鼠标单击两个变量名,你会发现它们两个所指
向内部字符串是同一个!也就是说在拷贝构造(赋值也一样)时并没有象我们想象的那
样进行内部字符串的复制!好了到现在为至我们至少不用为第一个问题担心了,没有了
字符串的复制,单单是对象的构造与析构算不了什么问题了(AnsiString只有一个Data
成员变量)。
  然而第二个问题就很严重了,再看下面的代码:

AnsiString src="test AnsiString";
AnsiString strTest=src; //拷贝构造
strTest[1]='x';
char* cp=strTest.c_str();
cp[0]='T';

运行结果就是我们的预期了,为什么加了句strTest[1]='x';就"正常"了呢?很明显
AnsiString为了我们第一个问题中的效率问题采用了copy on write技术,也就是只读
共享,写时拷贝。这样只有在对象要改变其内部数据的值时才做一份自己的拷贝然后在
自己的拷贝中进行修改(就种技术在操作系统中被广泛使用)。同时在对象析构时如果
引用计数大于0,数据也不会被删除,它保证数据的有效性。这样返回AnsiString变量的
函数也就没有严重的效率问题了。

  到目前为止,已经真象大白了,结论就是我们不用担心VCL中AnsiString变量传值的
效率问题,另外即使是传值得到的AnsiString对象,我们也不能对其内部数据直接进行
修改(否则你的程序的某些功能模块可以会出现第一次运行正常第二次后就乱七八糟),
尤其是在多线程环境下。原因就不必多说了,大不了复制一份了事。