C++中字符串String的一些函数原型
class String{
…
private:
char * m_data;
}
c++编译器会自动为一个类产生四个缺省的函数,如:无参的构造函数,拷贝构造函数,析构函数,赋值函数。
字符串拷贝函数strcpy的原型:
char *strcpy(char *strDest, const char *strSrc){
char *strTmp = strDest;
while((*strDest++ = *strSrc++) !=’\0’){
;
}
return strTmp;
}
析构函数:
String::~String(void){
delete []m_data;
}
构造函数:
String::String(const char *str){
if(str == NULL){
m_data = new char[1];
*m_data = ‘\0’;
}else{
m_data = new char[strlen(str) +1];
strcpy(m_data, str);
}
}
缺省的拷贝构造函数,缺省的赋值函数都是采用“位拷贝”,而非“值拷贝”的方式实现,如果类中含有指针变量,这两个函数都会出错,因为“位拷贝”拷贝的是地址(是memorycopy),实际需要的可能是拷贝内容的“值拷贝”(strcpy)。
以String类型来说,把str2赋值给str1,“位拷贝”意味着执行str1.m_data=str2.m_data;这里会有三个问题:1)str1.m_data原有的内存没有被释放,造成内存泄露;2)str1.m_data和str2.m_data指向同一块内存,所以一个变动会影响另一个;3)在对象被析构时,m_data会被释放两次。
拷贝构造函数是在对象被创建时调用的,而赋值函数只能被已经存在了的对象调用,如:
String str1(“abc”);
String str2(“123”);
String str3 = str1;//这里调用了拷贝构造函数,跟String str3(str1);写法相同。
str3 = str2;//这里调用了赋值函数
拷贝构造函数:
String::String(const String &other){
int length = strlen(other.m_data);
m_data = new char[length +1];
strcpy(m_data, other.m_data);
}
重载的赋值函数operate= 的原型:
String & String::operate=(const String &other){
//先判断自赋值
if(this == &other)
return *this;
//释放了原来的内存资源,也就无法做自己赋值给自己的操作了,所以前面要做自赋值判断。
delete []m_data;
m_data= new char[strlen(other.m_data)+];
strcpy(m_data, other.m_data);
return *this;
}
赋值函数的返回值类型是引用,返回*this的引用,不需要拷贝过程;如果用“值传递”,也就是说如果返回类型是值类型,功能没有问题,但是因为return语句要把*this拷贝到保存返回值的外部存储单元中,增加了不必要的开销,降低了赋值函数的效率。
重载String的相加函数operate+ 的实现:
String operate+(const String &s1, const String &s2){
String temp;
delete []temp.m_data;
temp.m_data = new char[strlen(s1.m_data)+strlen(s2.m_data)+1];
strcpy(temp.m_data, s1.m_data);
strcat(temp.m_data, s2.m_data);
return temp;
}
相加函数的返回值类型是值类型,如果使用“引用传递”,也就是返回值改为引用类型,功能就无法实现了,因为函数返回的是一个指向局部对象变量temp的引用,函数内的局部变量的存储单元是在栈空间的,由于temp在函数结束时被自动销毁,所以导致返回的引用无效了。