周末学习-String原理以及实现

15 篇文章 0 订阅
5 篇文章 1 订阅

String原理及实现

string类是由模板类basic_string<class _CharT,class _traits,class _alloc>实例化生成的一个类。basic_tring是由_String_base继承而来的。
在这里插入图片描述

typedef basic_string<char> string

#pragma once
#include<iostream>
class String
{
private:
	char*  data;   //字符串内容
	size_t length; //字符串长度
 
public:
	String(const char* str = nullptr);  //通用构造函数
	String(const String& str);          //拷贝构造函数
	~String();                          //析构函数
 
	String operator+(const String &str) const;  //重载+
	String& operator=(const String &str);       //重载=
	String& operator+=(const String &str);      //重载+=
	bool operator==(const String &str) const;   //重载==
 
        friend std::istream& operator>>(std::istream &is, String &str);//重载>>
	friend std::ostream& operator<<(std::ostream &os, String &str);//重载<<
 
	char& operator[](int n)const;               //重载[]
 
	size_t size() const;                        //获取长度
	const char* c_str() const;                  //获取C字符串
};

#include"String.h"
 
//通用构造函数
String::String(const char *str)
{
	if (!str)
	{
		length = 0;
		data = new char[1];  //一定要用new分配内存,否则就变成了浅拷贝;
		*data = '\0';
	}
	else
	{
		length = strlen(str); //
		data = new char[length + 1];
		strcpy(data,str);
	}
}
 
//拷贝构造函数
String::String(const String& str)
{
	length = str.size();
	data = new char[length + 1];  //一定要用new,否则变成了浅拷贝
	strcpy(data,str.c_str());
}
 
//析构函数
String::~String()
{
	delete[]data;
	length = 0;
}
 
//重载+
String String::operator+(const String &str) const  
{
	String StringNew;
	StringNew.length = length + str.size();
 
	StringNew = new char[length + 1];
	strcpy(StringNew.data, data);
	strcat(StringNew.data, str.data);  //字符串拼接函数,即将str内容复制到StringNew内容后面
	return StringNew;
}
 
//重载=
String& String::operator=(const String &str)       
{
	if (this == &str)
	{
		return *this;
	}
 
	delete []data;                 //释放内存
	length = str.length;
	data = new char[length + 1];
	strcpy(data,str.c_str());
	return *this;
}
 
//重载+=
String& String::operator+=(const String &str)      
{
	length += str.size();
	char *dataNew = new char[length + 1];
	strcpy(dataNew, data);
	delete[]data;
	strcat(dataNew, str.c_str());
	data = dataNew;
	return *this;
}
 
//重载==
bool String::operator==(const String &str) const   
{
	if (length != str.length)
	{
		return false;
	}
	return strcmp(data, str.data) ? false : true;
}
 
//重载[]
char& String::operator[](int n) const           //str[n]表示第n+1个元素   
{
	if (n >= length)
	{
		return data[length - 1]; //错误处理
	}
	else
	{
		return data[n];
	}
}
 
 //获取长度
size_t String::size() const                      
{
	return this->length;
}
 
//获取C字符串
const char* String::c_str() const                 
{
	return data;
}
 
//重载>>
 
std::istream& operator>>(std::istream &is, String &str)
{
	char tem[1000];
	is >> tem;
	str.length = strlen(tem);
	str.data = new char[str.length + 1];
	strcpy(str.data, tem);
	return is;
}
 
//重载<<
std::ostream& operator<<(std::ostream &os, String &str)
{
	os << str.c_str();
	return os;
}

关于operator>>和operator<<运算符重载,我们是设计成友元函数(非成员函数),并没有设计成成员函数,原因如下:对于一般的运算符重载都设计为类的成员函数,而>>和<<却不这样设计,因为作为一个成员函数,其左侧操作数必须是隶属同一个类之下的对象,如果设计成员函数,输出为对象>>cout >> endl;(Essential C++)不符合习惯。

一般情况下:

将双目运算符重载为友元函数,这样就可以使用交换律,比较方便

单目运算符一般重载为成员函数,因为直接对类对象本身进行操作

运算符重载函数可以作为成员函数,友元函数,普通函数。

普通函数:一般不用,通过类的公共接口间接访问私有成员。

成员函数:可通过this指针访问本类的成员,可以少写一个参数,但是表达式左边的第一个参数必须是类对象,通过该类对象来调用成员函数。

友元函数:左边一般不是对象。<< >>运算符一般都要申明为友元重载函数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值