码迷,mamicode.com
首页 > 其他好文 > 详细

String类的实现与思考

时间:2015-06-15 09:30:03      阅读:138      评论:0      收藏:0      [点我收藏+]

标签:

    对于字符串我们有时候很难向整型或其他变量那样进行比较和直接复制或定义,这都是C语言中遇到的问题,在C++ 中提供了一种类专门解决这种对于字符串的操作,叫做string类,我其实也想实现一下并且暂时浅浅的了解一下,以下是我简单的实现string类,我的string叫 String类注意大小写哦!!!!!!!!!

/*/**********************************************************************
* *   Copyright (c)2015,WK Studio
* *   Filename:  String.h
* *   Compiler: GCC  vs2013
* *   Author:WK
* *   Time: 2015 14 6
* **********************************************************************/
#include<iostream>
#include<string.h>
using namespace std;


class String
{
public:
	String(char * d) :data(d)
	{}
	//构造函数
	String(const char *str = NULL);
	~String();
	String(const String &s);
	String& operator=(const String &s);
	friend String operator + (const String& str1, const String& str2);
	
	String& operator+=(const String &str2);
	friend String& operator+=(String &str1, String &str2);

	friend bool operator!=(String &str1, String &str2);
	friend bool operator==(String &str1, String &str2);
	friend bool operator>(String &str1, String &str2);
	friend bool operator<(String &str1, String &str2);
	/*
	对“ << ”和“ >> ”重载的函数形式如下:
	istream & operator >> (istream &, 自定义类 &);
	ostream & operator << (ostream &, 自定义类 &);
	即重载运算符“ >> ”的函数的第一个参数和函数的类型都必须是istream&类型,第二个参数是要进行输入操作的类。重载“ << ”的函数的第一个参数和函数的类型都必须是ostream&类型,第二个参数是要进行输出操作的类。因此,只能将重载“ >> ”和“ << ”的函数作为友元函数或普通的函数,而不能将它们定义为成员函数。
	*/
	friend istream& operator>> (istream &is, String &str);//返回引用可以实现连续输入,并且返回值不存在与栈中所以可以返回引用
	friend ostream& operator<< (ostream &out, String &str);

private:
	char *data;
};
/*/**********************************************************************
* *   Copyright (c)2015,WK Studio
* *   Filename:  main.cpp
* *   Compiler: GCC  vs2013
* *   Author:WK
* *   Time: 2015 14 6
* **********************************************************************/


void main()
{

	
	String s1 = "Str";//调用构造
	String s2("ing");//调用构造

	String s3 = s1;//调用拷贝

	String s4("String");//调用构造
	s4 = s2;//调用赋值
	String s5;//调用构造
    s5 = s2;//调用赋值

	String s6("String");//调用构造
	s6 = s1 + s2;//调用+运算符重载函数返回临时无名对象通过临时无名对象调用赋值函数对s6进行赋值,之后临时无名对象被释放
	String s7;
	s7 = s1 + s2;//同上
	String  s8 = s1 + "123";//调用构造函数用"123"生成一个临时对象来和s1进行相加调用+运算符重载

   String s9 = s1 + s2;//+运算符重载返回的临时无名对象直接用来拷贝构造s8对象

   String s10;
   s10+= s1;//如果+=运算符重载的友员和成员函数都存在调用的是友元函数
   //s9.operator+=(s1);//调用成员函数
   //operator+=(s9,s1);//可以直接调用友员函数,因为友员函数属于类无需对象来驱动
   //String s10 += s2; 
   //上面这种不可以是因为在+=之前是s10对象还没有构造呢
   //类似于int a = 10;  int b+= a;  int c+=1;
   String ss("1");
   String ss1("1");
   cout << (s1 != s2) << "\n";
   cout << (ss != ss1) << "\n";
   cout << (ss == ss1) << "\n";
   cout << (s1 == s2) << "\n";

   cout << (s1 > s2) << "\n";
   cout << (s1 < s2) << "\n";
   String s11;
   cin >> s11;

   cout << s11;
   getchar();
	
}
/*/**********************************************************************
* *   Copyright (c)2015,WK Studio
* *   Filename: String.cpp
* *   Compiler: GCC  vs2013
* *   Author:WK
* *   Time: 2015 14 6
* **********************************************************************/
#include"String.h"
//构造函数
String::String(const char *str)
{
	cout << "Create String!" << this << "\n";
	if (str == NULL)
	{
		data = new char[1];//至少有一个'\0'
		data[0] = '\0';
	}
	else
	{
		data = new char[strlen(str) + 1]; //(char *)malloc(strlen(str)+1);
		strcpy(data, str);
	}
}
/*//构造函数1
String(const char *str = NULL)
{
if(str == NULL)
{
str=NULL;    //不能满足当字符串为NULL时候
}
else
{
data = new char[strlen(str)+1];//(char *)malloc(strlen(str)+1);
strcpy(data,str);
}
}
//构造函数2
String(const char *str = "")//不能满足当字符串为NULL时候
{
data = new char[strlen(str)+1];//(char *)malloc(strlen(str)+1);
strcpy(data,str);
}
*/
//拷贝构造
String::String(const String &s)
{
	cout << "Copy String!" << this << "\n";
	data = new char[strlen(s.data) + 1];
	strcpy(data, s.data);
}

//= 运算符重载
String& String:: operator=(const String &s)//返回引用可以实现连等
{
	cout << "Assignment String!" << this << "\n";
	if (this != &s)   //(1) 检查自赋值
	{
		free(this->data);  // (2) 释放原有的内存资源
		this->data = NULL;
		this->data = new char[strlen(s.data) + 1];// (3)分配新的内存资源,并复制内容
		strcpy(this->data, s.data);
	}
	return *this;    // (4)返回本对象的引用
}
/*
String& operator=(const String &s)
{
if(this==&s)//(1) 检查自赋值
{
return *this;
}
free(this->data); // (2) 释放原有的内存资源
data=NULL;

data=new char[strlen(s)+1];//(3)分配新的内存资源,并复制内容
strcpy(data,s.data);

return *this; // (4)返回本对象的引用

}
*/
//运算符+重载为友员函数
String operator + (const String& str1, const String& str2)//不可以返回引用,因为这里在函数栈中建立了一个临时的对象,具体讨论青参照我的这篇文章
{
	String str;//临时对象调用构造函数
	delete[] str.data;
	str.data = NULL;
	str.data = new char[strlen(str1.data)+strlen(str2.data) + 1];
	strcpy(str.data, str1.data);
	strcat(str.data, str2.data);
	cout << "+ operator String!"<< "\n";
	return str;//这里会调用拷贝构造函数用str对象拷贝构造临时无名对象,之后在栈中将临时对象释放
}
//+=运算符重载为成员函数
String& String:: operator+=(const String &str2)
{
	if (this != &str2)
	{
		*this = *this + str2;
	}
	cout << "+=运算符成员函数重载!\n";
	return *this;
}
//+=运算符重载为友元函数
String& operator+=(String &str1, String &str2)//可以返回引用,因为这里的str1超过这个函数栈还存在
{
	if (&str1 != &str2)//当将!=运算符重载之后可以使用(str1!=str2)进行判断了
	{
		str1 = str1 + str2;
	}
	cout<< "+=运算符友员函数重载!\n";
	return str1;
}
//!=重载函数
bool operator!=(String &str1, String &str2)
{
	if (!strcmp(str1.data, str2.data))
	{
		cout << "These String is equal!\n";
		return false;
	}
	cout << "These String is  not equal!\n";
	return true;

}

//==运算符重载
bool operator==(String &str1, String &str2)
{

	if (!strcmp(str1.data, str2.data))
	{
		cout << "These String is equal!\n";
		return true;
	}
    cout << "These String is  not equal!\n";
    return false;

}
//重载流提取运算符“>>”
istream& operator>> (istream &in, String &str)//is是cin的引用,cin是类istream的对象
{
	cout << "Please input string:(end of 'ctrl+Z')  ";
	char c[101] = { 0 };//缓冲区为100byte大小
	char ch = 0;
	int i(0);//等价于 i=0;
	while ( in>> ch  )
	{
		c[i] = ch;
		i++;
	}
	delete[]str.data;
	str.data = new char[i + 1];
	strcpy(str.data, c);

	return in;

}
//重载流插入运算符“ << ”
ostream& operator<< (ostream &out, String &str)//is是cout的引用,cout是类ostream的对象
{

	out<< str.data;
	return out;

}

 bool operator>(String &str1, String &str2)
{
	if (strcmp(str1.data, str2.data) == 1)
	{
		cout << "First String is big!";
		return true;
	}
	cout << "Second String is big!";
	return false;
}
 bool operator<(String &str1, String &str2)
{
	if (strcmp(str1.data, str2.data) == 1)
	{
		cout << "First String is big!\n";
		return false;
	}
	cout << "Second String is big!\n";
	return true;

}
//析构函数
String::~String()
{
	cout << "Free String!" << this << "\n";
}
技术分享





String类的实现与思考

标签:

原文地址:http://blog.csdn.net/kai8wei/article/details/46494255

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!