String类基本实现

本文详细解析了一个自定义C++字符串类的实现过程,重点讨论了内存分配、释放以及复制控制的注意事项。通过实例代码展示了如何正确地管理字符串类中的指针,避免内存泄漏和堆破坏等问题,旨在帮助开发者在类似场景下编写更健壮的代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在类中如果有一个成员函数为指针就别特要注意复制控制和内存管理的问题了,借用String类模拟这些情况,里面需要注意的问题很多,在写下面这个程序时,很多细节的地方我是花了很长时间慢慢看的。写出来方便以后每次查看时能够注意这些小问题,

有几个基本的原则:1 在使用指针前,一定要确定该指针能够使用,即指针的指向或者指针后面的内存分配(初始化)

     2 每次分配了内存就一定要释放掉内存

     3 复制控制里面一般复制控制函数,复制操作符重载,析构函数三个一般同时出现

下面是代码,没有什么组织,慢慢看就行了:

       

#include <iostream>
#include <ostream>
#include <istream>
#include <string.h>
#include <string>


/*
	这个很有示范作用,关于内存分配,在创建一个String()对象时
	默认调用第一个构造函数,但是如果对这个对象使用cin操作符
	基本上会出错,这里不清楚STL标准库中的string的内存分配方式,
	调试跟踪显示的策略好像是先分配16字节的字符,如果超过之后
	每次进行重新分配,如果要写的话肯定很长,在后面的测试用我
	使用了cin操作符,但是如果每次输入的长度超过预先分配的内存
	在析构这个对象时,也就是调用delete [] str时,会出现heap
	heap corruption detected这个错误,具体的引起这个错误的原因
	很多,但是最后只有一个就是内存分配出现错误,详细的资料网上
	介绍很多,这里在我们编写自己的类时不建议采用这种方式,即需要
	自己管理内存,并且需要对指针进行内存分配的方式,尽量采用stl
	内置的标准库,如果设计到必须要求较高性能时,或者必须要对内存
	进行严格的控制时,这就需要规划整个工程了。会有专门管理内存
	的类。
*/
using namespace std;
const int MAXN  = 128;
class String{
public:
	String();
	String(const char *);
	String(const String &s);
	String &operator = (const String &s);
	~String();
public:
	char* getString() const;
	void setString(char *str);
	String operator +=(const String &s);

	char operator [](int index) const;

	friend String operator+(const String &s1,const String &s2);

	friend std::ostream& operator <<(std::ostream &,const String &obj) ;
	friend std::istream& operator >>(std::istream &,const String &obj) ;

	friend bool operator == (const String &s1,const String &s2);
	friend bool operator < (const String &s1,const String &s2);



private:	
	char *str;				//如果需要自己管理内存 那绝对是灾难性的工程,需要尽量使用标准库
	//	int len;
//	std::string;
};

String::String(){
	str = NULL;
	str = new char[MAXN];
	//str = NULL;
}

String::String(const String &s){
	if(s.str == NULL)	
		str = NULL;
	else{
		str = new char[strlen(s.str)+1];
		strcpy(str,s.str);
	}
	//str = s.str;
}

String::String(const char *s){
	if( s == NULL )
		str = NULL;
	else{
		str = (char *)malloc(sizeof(char)*strlen(s)+1);
		strcpy(str,s);
	}
}

String& String::operator= (const String &s){
	//str = s.str;
	if(s.str == NULL)
		str = NULL;
	else{
		str = new char[strlen(s.str)+1];
		strcpy(str,s.str);
	}
	return *this;
}

void String::setString(char *s){
	if(s == NULL ) 
		str = NULL;
	str = new char(strlen(s) +1);
	strcpy(str,s);
}

char* String::getString() const{
	return str;
}

String String::operator+=(const String &s1){
	char *tmp = new char(strlen(s1.str)+1);
	if(tmp == NULL){
		std::cerr << "new memory wrong!";
		exit(1);
	}	
	strcpy(tmp ,s1.str);
	strcat(str,tmp);
	delete tmp;
	return *this;
}

char String::operator[](int index) const{
	return str[index];
}

String operator+(const String&s1 ,const String &s2){
	char *tmp = new char(strlen(s1.str)+strlen(s2.str)+1);
	if( !tmp ){
		std::cerr << "memory allocated errer" ;
		exit(1);
	}
	//s1.operator+=(s2);
	strcpy(tmp,s1.str);	
	strcat(tmp,s2.str);
	String s(tmp);		
	delete tmp;
	return s;

}

std::ostream &operator <<(std::ostream &out,const String &obj){
	out << obj.str;
	return out;
}


std::istream &operator >>(std::istream &in,const String &obj){
	in >> obj.str;
	return in;
}

bool operator ==(const String &s1,const String &s2){
	if(strcmp(s1.str,s2.str) == 0)
		return true;
	return false;
}


bool operator < (const String &s1,const String &s2){
	if(strcmp(s1.str,s2.str) < 0)
		return true;
	return false;
}


String::~String(){
	//	if(str != NULL )
	delete str;
	str = NULL;
}


int main(){
	char *str ="weichong";
	String s ="longge";
	//	String s = new String(str);
	char *t = s.getString();
	std::cout << t << std::endl;
	String s1 = s;

	t = s1.getString();
	std::cout << t << std::endl;

	String s2(str);
	t = s2.getString();
	std::cout << t << std::endl;

	String s3(s2);
	t = s3.getString();
	std::cout << t << std::endl;

	//	std::string stest;
	//	std::cin >> stest;
	//	std::cout << "standard string " <<stest <<std::endl;

	String stt;		//这样的话 根本不能直接使用,需要预先分配好内存 
	std::cin >> stt ;
	std::cout  << "operator  >> & <<" << stt <<std::endl;

	String stt1;
	std::cin >> stt1;

	if(stt < stt1){
		std::cout << "operator []"<<stt[0]  <<" "<< stt1[0] <<std::endl;
		std::cout << "operator <" <<std::endl;
	}
	if(stt == stt1){
		std::cout << "operator ==" <<stt <<" " <<stt1 <<std::endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值