string类的构造、析勾 、赋值、拷贝构造、输出运算符重载、加法重载、比较运算符重载、以及类型转换等,均在代码中实现,含详细注释
。
#include<iostream>
#include<assert.h>
using namespace std;
#include<string.h>
#pragma warning(disable:4996)
class String;
ostream& operator<<(ostream &out,const String & str);//输出运算符一般声明为友元,在类外实现
class String
{
friend ostream& operator<<(ostream &out,const String & str);
public://默认为私有
//构造函数
String(char * str ="")
{
if (str == NULL)
{
m_str = new char[1];
m_str[0] = '\0';
}
else
{
m_str = new char[strlen(str) + 1];
strcpy(m_str, str);
}
}
String(char c)
{
m_str = new char[2];
m_str[0] = c;
m_str[1] = '\0';
}
String(char c, int n)
{
m_str = new char[n + 1];
memset(m_str, c, n);
m_str[n] = '\0';
}
//拷贝构造函数 (深拷贝)
String(String & s)
{
m_str = new char[strlen(s.m_str) + 1];
strcpy(m_str, s.m_str);
}
//析勾函数
~String()
{
if (m_str != NULL)
{
delete[]m_str;//必须给出释放数组信息[]
m_str = NULL;
}
}
public:
//加号运算符的重载(值返回)-->优点不改变this 数据,产生新对象,缺点要构造新对象,调动构造函数,调动拷贝构造函数
String operator+(String &s)
{
char * p = new char[strlen(m_str) + strlen(s.m_str) + 1];//动态开辟空间
//char p[20] = ""; //静态开辟
strcpy(p, m_str);
strcat(p, s.m_str);
String t(p);//对象返回,实例化对象
delete[]p;//用完就释放
p = NULL;//预防野指针
return t; //返回t对象
}//t对象调动 构造 拷贝 析勾
/*
//加号运算符的重载(引用返回) -> 优点不调动构造,拷贝构造,缺点也修改了this
String & operator+(String &s)
{ //先把this中的字符串拷贝到动态开辟的p空间
char * p = new char[strlen(m_str) + 1];
strcpy(p, m_str);
//再释放m_str空间
if (m_str != NULL)
delete[]m_str;
m_str = NULL;
//然后 重新开辟当前对象m_str所指的空间,先拷贝再连接
m_str = new char[strlen(p) + strlen(s.m_str) + 1];
strcpy(m_str, p);
strcat(m_str, s.m_str);
//最后释放p空间呢
delete[]p;
//返回 当前对象所指的数据成员
return *this;
}
*/
//赋值运算符的重载 =
String& operator=(const String & s)
{
//自赋值判断,对象给对象赋值?1提高效率,2对象中有指针p =_p 自赋值错误
if (this == &s)
return *this;
//先析勾
if (m_str != NULL)
{
delete[]m_str;
m_str = NULL;
}
//拷贝构造
m_str = new char[strlen(s.m_str) + 1];
strcpy(m_str, s.m_str);
return *this;
}
String& operator=(char *s)
{//非对象,不需要判断自赋值
if (m_str != NULL)//析勾
{
delete[]m_str;
m_str = NULL;
}
m_str = new char[strlen(s) + 1];//拷贝构造
assert(m_str != NULL);
strcpy(m_str, s);
return *this;//返回当前对象
}
String& operator=(char ch)
{
if (m_str != NULL)//析勾
{
delete[]m_str;
m_str = NULL;
}
m_str = new char[2];//拷贝构造
m_str[0] = ch;
m_str[1] = '\0';
return *this;//返回当前对象
}
char& operator[](int i)
{
assert(i >= 0 && i < strlen(m_str));
return m_str[i];
}
bool operator==(String &s)
{
return strcmp(m_str, s.m_str ) == 0;
}
bool operator>(String &s)
{
return strcmp(m_str, s.m_str) > 0;
}
bool operator<(String &s)
{
return strcmp(m_str, s.m_str) < 0;
}
operator char*()//转换函数,将对象转换成基本的数据类型,无返回值
{
return m_str;
}
private:
char * m_str;
};
ostream& operator<<(ostream &out, const String & str)
{
out << str.m_str;
return out;
}
void main()
{
String a("12345678");
String b('|');
a = b;
cout << a << endl;
//char A = 'B';
a = 'A';
cout << a << endl;
a = "qwere";
cout << a << endl;
a[1];
cout << a[1] << endl;
cout << "---------------" << endl;
cout << (char*)a << endl;;
}
。