#pragma once
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
class errorOutRange
{
};
//字符串模板库的实现 参考http://edu.51cto.com/lesson/id-86642.html
template <class T=char>
class String
{
public:
String();
~String();
String(const T* p);//char* 构造函数
String(const String& str);//拷贝构造函数
void operator = (const String& str);//赋值构造函数
String operator + (const String& str);
void operator += (const String& str);
T operator [](int id);
void show();
//流式运算符重载
friend ostream& operator <<(ostream& o, const String<T> &str)
{
o << str.pStart;
return o;
};
private:
T* pStart=nullptr;
int length = 0;
};
#define _CRT_SECURE_NO_WARNINGS
#include "String.h"
template <class T>
String<T>::String() :pStart(nullptr),length(0)
{
}
template <class T>
String<T>::String(const T* p)
{
//c++需要严格注意类型匹配。
if (strcmp(typeid(T).name(), "char")==0)
{
this->length = strlen(reinterpret_cast<const char*>(p))+1;//字符串长度需要加1 \0
this->pStart = new T[this->length];
strcpy(reinterpret_cast<char*>(this->pStart), reinterpret_cast<const char*>(p));
}
else if (strcmp(typeid(T).name(), "wchar_t") == 0)
{
this->length = wcslen(reinterpret_cast<const wchar_t*>(p))+1;
this->pStart = new T[this->length];
wcscpy(reinterpret_cast<wchar_t*>(this->pStart), reinterpret_cast<const wchar_t*>(p));
}
else
{
cout << "类型不匹配,请检查输入的类型" << endl;
}
}
template <class T>
void String<T>::operator = (const String& str)
{
//释放原来的数据
if (this->pStart != nullptr)
{
delete[] this->pStart;
}
this->length = 0;
this->length = str->length;
this->pStart = new T[this->length];
if (strcmp(typeid(T).name(), "char") == 0)
{
strcpy(reinterpret_cast<char*>(this->pStart), reinterpret_cast<const char*>(str->pStart));
}
else if (strcmp(typeid(T).name(), "wchar_t") == 0)
{
wscpy(reinterpret_cast<wchar_t*>(this->pStart), reinterpret_cast<const wchar_t*>(str->pStart));
}
else
{
cout << "类型不匹配,请检查输入的类型" << endl;
}
}
template <class T>
T String<T>::operator [](int id)
{
if (id<0 || id>=this->length)
{
throw errorOutRange();
}
return this->pStart[id];
}
template <class T>
String<T>::String(const String& str)
{
//拷贝构造函数需要释放原来的数据
if (this->pStart != nullptr)
{
delete[] this->pStart;
}
this->length = 0;
this->length = str.length;
this->pStart = new T[this->length];
if (strcmp(typeid(T).name(), "char") == 0)
{
strcpy(reinterpret_cast<char*>(this->pStart), reinterpret_cast<const char*>(str.pStart));
}
else if (strcmp(typeid(T).name(), "wchar_t") == 0)
{
wcscpy(reinterpret_cast<wchar_t*>(this->pStart), reinterpret_cast<const wchar_t*>(str.pStart));
}else
{
cout << "类型不匹配,请检查输入的类型" << endl;
}
}
template <class T>
void String<T>::show()
{
if(strcmp(typeid(T).name(), "char") == 0)
{
cout << reinterpret_cast<char*>(this->pStart) << endl;
}
else if (strcmp(typeid(T).name(), "wchar_t") == 0)
{
wcout << reinterpret_cast<wchar_t*>(this->pStart) << endl;
}else
{
cout << "类型不匹配,请检查输入的类型" << endl;
}
}
template <class T>
String<T>::~String()
{
if (this->pStart!= nullptr)
{
delete[] this->pStart;
}
}
//返回对象需要实例化 String<T>
template <class T>
String<T> String<T>::operator + (const String& str)
{
String<T> strTemp;
strTemp.length = this->length + str.length - 1;
strTemp.pStart = new T[strTemp.length];
if (strcmp(typeid(T).name(), "char") == 0)
{
strcpy(reinterpret_cast<char*>(strTemp.pStart), reinterpret_cast<char*>(this->pStart));
strcat(reinterpret_cast<char*>(strTemp.pStart), reinterpret_cast<const char*>(str.pStart));
}
else if (strcmp(typeid(T).name(), "wchar_t") == 0)
{
wcscpy(reinterpret_cast<wchar_t*>(strTemp.pStart), reinterpret_cast<wchar_t*>(this->pStart));
wcscat(reinterpret_cast<wchar_t*>(strTemp.pStart), reinterpret_cast<const wchar_t*>(str.pStart));
}
else
{
cout << "类型不匹配,请检查输入的类型" << endl;
}
//会调用拷贝构造函数
return strTemp;
}
template <class T>
void String<T>::operator += (const String& str)
{
//"123" 4 "1234" 5
this->length += (str.length-1);//长度
T* temp = new T[this->length];
if (strcmp(typeid(T).name(), "char") == 0)
{
strcpy(reinterpret_cast<char*>(temp), reinterpret_cast<char*>(this->pStart));
strcat(reinterpret_cast<char*>(temp), reinterpret_cast<const char*>(str.pStart));
delete[] this->pStart;
this->pStart = temp;//拷贝
}
else if (strcmp(typeid(T).name(), "wchar_t") == 0)
{
wcscpy(reinterpret_cast<wchar_t*>(temp), reinterpret_cast<wchar_t*>(this->pStart));
wcscat(reinterpret_cast<wchar_t*>(temp), reinterpret_cast<const wchar_t*>(str.pStart));
delete[] this->pStart;
this->pStart = temp;//拷贝
}
else
{
cout << "类型不匹配,请检查输入的类型" << endl;
}
}
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
#include <cstdlib>
#include "String.h"
#include "String.cpp" //template类需要连接源文件
using namespace std;
int main1()
{
//String<char> str1;
//String<wchar_t> str2;
String<char> str1("hello");
str1.show();
String<wchar_t> str2(L"world");
str2.show();
cin.get();
return 0;
}
void test()
{
String<char> str1("test");
str1.show();
}
void main2()
{
String<char> str1("hello");
str1.show();
String<wchar_t> str2(L"world");
str2.show();
test();
cin.get();
}
void main3()
{
String<char> str1("hello");
String<char> str2("world");
str1 += str2;
str1.show();
(str1 + str2).show();
String<char> str3=str1+str2;
str3.show();
cin.get();
}
void main4()
{
String<wchar_t> str1(L"hello");
String<wchar_t> str2(L"java");
str1 += str2;
str1.show();
(str1 + str2).show();
String<wchar_t> str3 = str1 + str2;
str3.show();
cin.get();
}
void main()
{
//默认模板
String<> str1("hello");
String<> str2("world");
String<> str3 = str1 + str2;
str3.show();
str1 += str2;
str1.show();
//测试流运算符。
cout << str1 << endl;
cout << str2 << endl;
cout << str3 << endl;
cin.get();
}
学习c++模板和运算符重载的例子