String基本实现

#ifndef _STRING_H_
#define _STRING_H_

#include <iostream>
using namespace std;

class String
{
public:
	/*explicit*/ String(const char* str= "");
	// 复制构造函数
	// 不重载复制构造函数,则会调用系统默认的复制构造函数,实现的是浅拷贝  
	// 浅拷贝:String s("AAAA"); String s2 = s;  等价于  s2.str_ = s.str_;  
	// 在s2生命周期结果,s2.str_被析构,接着s.str_再次析构,则出现异常
	String(const String& other);
	// 赋值操作运算符重载
	// 赋值操作运算符 String s1("AAAA");  String s2 = s1; 等价于 s2.str_ = s1.str_; 
	// 调用的是系统默认的赋值操作运算符 实现的是浅拷贝,在s2生命周期结果,s2.str_被析构,接着s1.str_再次析构,则出现异常
	String& operator=(const String& other);
	String& operator=(const char* str);
	bool operator!() const;
	// []运算符重载
	// 返回值为引用:1、不重新创建字符串对象,2、返回引用可以对该引用进行赋值,进而达到修改String.str_的值
	char& operator[](unsigned int index);
	// 返回值为const 引用: 当const String s2("abcdef");  s2对象的str_数据是不能被修改
	// 申明const: s2是const 对象, 则在该成员函数内均不能被修改
	const char& operator[](unsigned int index) const;
	// +运算符重载
	// 建议使用友元的方式来实现; 不建议使用成员函数实现:原因是成员函数的默认第一个形参是类型自身的引用 如不能实现: String s = s1 + s2;
	// 返回值 类型对象: 原因是+运算符是对象与对象相加,对象与字符串相加 从而得到新的对象
	// 形参:对象的引用, 不调用构造函数
	friend String operator+(const String& s1, const String& s2);
	// +=运算符重载
	// 建议使用成员函数实现,原因是第一个形参就是自身引用
	// 返回自身引用
	String& operator+=(const String& other);
	// << 流运算符重载
	friend ostream& operator<<(ostream& os, const String& str);
	// >> 流运算符重载
	friend istream& operator>>(istream& is, String& str);

	~String();

	void Display() const;

private:
	char* AllocAndCpy(const char* str);
	char* str_;
};
#endif // _STRING_H_
#pragma warning (disable:4996)

#include "String.h"
#include <string.h>

#include <iostream>
using namespace std;

String::String(const char* str)
{
	// 分配内存 赋值
	/*int len = strlen(str) + 1;
	str_ = new char[len];
	memset(str, 0, len);
	strcpy(str, str_);*/
	str_ = AllocAndCpy(str);
}

// 复制各构造函数:深拷贝  
String::String(const String &other)
{
	str_ = AllocAndCpy(other.str_);
}

String& String::operator=(const String& other)
{
	// 将原来str_空间进行删除
	delete[] str_;
	str_ = AllocAndCpy(other.str_);
	return *this;	
}

String& String::operator=(const char* str)
{
	delete[] str_;
	str_ = AllocAndCpy(str);
	return *this;
}
bool String::operator!() const
{
	return (strlen(str_) != 0);
}


// 当const 与 non const 的函数体实现一样时:建议non const 调用const
char& String::operator[](unsigned int index)
{
	//return str_[index];
	// const_cast<>  去除const限定
	// static_cast<> 加上const限定
	return const_cast<char&>(static_cast<const String&>(*this)[index]);
}

const char& String::operator[](unsigned int index) const
{
	return str_[index];
}

String operator+(const String& s1, const String& s2)
{
	/*size_t len = strlen(s1.str_) + strlen(s2.str_) + 1;
	char* newstr = new char[len];
	memset(newstr, 0, len);
	strcpy(newstr, s1.str_);
	strcat(newstr, s2.str_);

	String temp(newstr);
	delete[] newstr;
	return temp;*/

	String str = s1;
	str += s2;
	return str;
}

String& String::operator+=(const String& other)
{
	size_t len = strlen(str_) + strlen(other.str_) + 1;
	char* newstr = new char[len];
	memset(newstr, 0, len);
	strcpy(newstr, str_);
	strcat(newstr, other.str_);

	delete[] str_;
	str_ = newstr;
	return *this;
}

String::~String()
{
	delete[] str_;
}

char* String::AllocAndCpy(const char* str)
{
	size_t len = strlen(str) + 1;
	char* newstr = new char[len];
	memset(newstr, 0, len);
	// warning C4996: “strcpy”被声明为否决的  取消警告 #pragma warning(disable:code)
	strcpy(newstr, str);
	return newstr;
}

void String::Display() const
{
	cout<<str_<<endl;
}

// char* str.str_ 已经实现了os输出流重载
ostream& operator<<(ostream& os, const String& str)
{
	os<<str.str_;
	return os;
}

istream& operator>>(istream& is, String& str)
{
	char temp[1024];
	cin>>temp;
	str = temp;
	return is;
}

#include "String.h"
#include <iostream>
using namespace std;

int main(void)
{
	// [] 运算符重载
	String s1("abcdef");
	char c = s1[2];
	cout<<c<<endl;
	s1[2] = 'B';
	//s1.Display();

	// 当String对象是const 时,使用[]运算符是不能进行赋值的
	const String s2("abcdfs");
	//s2[2] = 'M';     //error C3892: “s2”: 不能给常量赋值
	//s2.Display();

	// + 运算符重载
	String s3 = "AAAAA";
	String s4 = "VVVVV";
	String s5 = s4 + s3;
	//s5.Display();

	String s6 = "XXXX" + s3 + "3131";
	//s6.Display();

	s3 += s4;
	//s3.Display();

	cout<<s3<<s4<<endl;

	String s7;
	cin>>s7;
	cout<<s7<<endl;


	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值