1 char字符串以'/0'结尾,但是strlen()时它不占大小,cout时它也不会输出来
2 new出来的char[]大小一定要满足操作,否则操作越界,delete时出错
new出来的指针移动了,delete也会出错
3 模板函数的声明和定义要放在同一个文件里,默认放在头文件
strings.h:
#pragma once
#include<string>
class strings
{
public:
strings();
strings(const char* s);
strings(const strings & other); //拷贝构造函数
strings(int n, char c); //常见一个包含n个字符为c的对象
strings(const char* s, int n); //将字符串初始化为s的前n个字符,即使已经到了串尾
template<class T>
strings(const T ptr1, const T ptr2);//用一个数组内的两个指针构造对象
int size();
strings& operator=(const strings& other);
strings operator+(const strings& other);
bool operator==(const strings& other);
char operator[] (int index);
friend std::ostream& operator<<(std::ostream& out, const strings& str);
virtual ~strings();
private:
char* date;
int datelength;
};
template<class T>
strings::strings(const T ptr1, const T ptr2)
{
T temp = ptr1;
int size = sizeof(*ptr1);
datelength = strlen(ptr1) - strlen(ptr2);
date = new char[datelength + 1];
int i = 0;
for (temp; temp<ptr2; temp += size)
{
date[i++] = *temp;
}
date[datelength] = '\0';
}
strings.cpp
#include "stdafx.h"
#include "strings.h"
#include<string>
#include<iostream>
strings::strings() //默认构造空字符串,'\0'不占长度
{
datelength = 0;
date = new char[1];
*date = '\0';
}
strings::strings(const char* s)
{
if (!s) //如果s为nullptr,则会为其初始化为空字符串,即以'\0'结尾
{
datelength = 0;
date = new char[1];
*date = '\0';
}
else
{
datelength = strlen(s);
date = new char[datelength+1];//最后空间放'\0'
strcpy(date, s);
}
}
strings::strings(const strings & other) //other字符串已经被初始化,因此不可能为nullptr,不需要判断为空
{
datelength = other.datelength;
date = new char[datelength + 1];
strcpy(date, other.date);
}
strings::strings(int n, char c)
{
datelength = n;
date = new char[datelength + 1];
for (int i = 0; i < datelength; i++)
date[i] = c;
date[datelength] = '\0'; //不能是date[datelength+1],否则越界,析构时出错
}
strings::strings(const char* s, int n)
{
datelength = n;
date = new char[datelength + 1];
strncpy(date, s, n);
date[datelength] = '\0';
}
strings& strings::operator=(const strings& other)
{
if (this->date == other.date)
return *this;
delete[] date;
datelength = other.datelength;
date = new char[datelength + 1];
strcpy(date, other.date);
return *this;
}
strings strings::operator+(const strings& other)
{
strings temp;
datelength = this->datelength + other.datelength;
temp.datelength = datelength; //大小别忘了更新,否则后面赋值的时候越界
temp.date = new char[temp.datelength + 1];
strcpy(temp.date, date);
strcat(temp.date, other.date);//要保证目标字符串由足够空间
return temp; //这里要注意,它返回的是临时对象,因此函数返回值不能为引用
}
bool strings::operator==(const strings& other)
{
if (this->datelength != other.datelength)
return false;
else
return strcmp(this->date, other.date) ? false : true;
}
char strings::operator[] (int index)
{
if (index >= 0 && index < this->datelength)
return this->date[index];
}
std::ostream& operator<<(std::ostream& out, const strings& str)
{
out << str.date;
return out;
}
strings::~strings()
{
if (this->date)
{
delete [] this->date;
this->date= nullptr;
}
}
main函数:
// String.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include"strings.h"
#include<iostream>
#include<cstdlib>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
strings a;
cout << "默认构造函数: " << a << endl;
strings b("zhang");
cout << "字符串构造: " << b << endl;
strings c(b);
cout << "拷贝构造函数: " << c << endl;
strings d(5, '6');
cout << "构造由5个‘6’组成的对象: " << d << endl;
char *str= "123456";
strings e(str, 3);
cout << "用字符串的前3个字符构造对象: " << e<< endl;
a = b;
cout << "赋值号重载:" << a << endl;
bool result = (a == b);
cout << "等于号重载:" << result << endl;
a = a + b;
cout << "加号重载:" << a << endl;
cout << "大小:"<<a.size() << endl;
char* ss = "123456";
strings bb(&ss[0], &ss[3]);
cout << "用字符串的两个指针构造对象:" << bb << endl;
system("pause");
return 0;
}