【C/C++】【练习】自己实现String类

手撕String,面试中经常会问到,今天我们自己实现并梳理MyString类,同时加深对拷贝构造,移动构造;运算符重载的理解;

成员变量

字符串MyString类中两个成员变量

  • char *的字符串m_data;
  • 保存字符串大小的m_size;

构造函数和析构函数

MyString(const char* str = nullptr); //函数默认参数为nullptr
~MyString();

//如果没有默认值,即str = nullptr;m_size = 0;m_data[0] = ‘\0’;
//否则,new 指定大小的堆内存,然后将内容拷贝到m_data;
MyString::MyString(const char* str)
{
	if (str == nullptr)
	{
		m_data = new char[1];
		m_data[0] = '\0';
		m_size = 0;
	}
	else
	{
		m_size = strlen(str);
		m_data = new char[m_size + 1];
		strcpy(m_data, str);
	}
}

//释放之前分配的内存
MyString::~MyString()
{
	delete[] m_data;
}

拷贝构造和拷贝赋值(深拷贝)

MyString(const MyString& str);
MyString& operator=(const MyString& str);

//分配指定大小的内存,直接使用strcpy拷贝;
//为什么不先delete ???
MyString::MyString(const MyString& str)
{
	m_size = str.m_size;
	m_data = new char[m_size + 1];
	strcpy(m_data, str.m_data);
}


//判断是不是自己给自己赋值
//如果不是,先释放原有的堆内存,然后重新分配指定大小的内存,使用strcpy拷贝;
//返回本对象的引用;
MyString& MyString::operator=(const MyString& str)
{
	if (this == &str)
		return *this;

	delete[] m_data;
	m_size = str.m_size;
	m_data = new char[m_size + 1];
	strcpy(m_data, str.m_data);
	return *this;
}


移动构造和移动赋值

MyString(MyString&& str);
MyString& operator=(MyString&& str);

//将当前指针m_data指向str.m_data;同时修改大小;
//让str.m_data置空;
MyString::MyString(MyString&& str)
{
	m_size = str.m_size;
	m_data = str.m_data;
	str.m_data = nullptr;
}


//判断是不是自己移动给自己
//如果不是,先释放原有的堆内存,然后改变指针的指向;并将str.m_data置空
//返回本对象的引用;
MyString& MyString::operator=(MyString&& str)
{
	if (this == &str)
		return *this;

	delete[] m_data;
	m_size = str.m_size;
	m_data = str.m_data;
	str.m_data = nullptr;
	return *this;
}

重载关系运算符

bool operator==(const MyString& str);
bool operator>(const MyString& str);
bool operator<(const MyString& str);

bool MyString::operator==(const MyString& str)
{ 
	if (strcmp(m_data, str.m_data) == 0)
		return true;
	return false;
}
bool MyString::operator>(const MyString& str)
{
	return strcmp(m_data, str.m_data) > 0;
}
bool MyString::operator<(const MyString& str)
{
	return strcmp(m_data, str.m_data) < 0;
}

重载+和[]

MyString operator+(const MyString& str);
char& operator[](int idx);

MyString MyString::operator+(const MyString & str)
{
	//统计长度
	int len = m_size + str.m_size;
	
    //结果字符串
	MyString res;
	delete []res.m_data;
	
    //重新分配内存
	res.m_data = new char[len + 1];
	//先清空
    memset(res.m_data, 0, len + 1);
    //依次将两个字符串接在后面
	strcat(res.m_data, this -> m_data);
	strcat(res.m_data, str.m_data);
	return res;
}

char& MyString::operator[](int idx)
{
	return m_data[idx];
}

重载输入>>和输出<<

//类外部的函数,要访问MyString的私有成员,设为友元函数
friend ostream & operator<<(ostream& os, const MyString& str);
friend istream& operator>>(istream& is, MyString& str);

ostream & operator<<(ostream& os, const MyString& str)
{
	os << str.m_data;
	return os;
}

istream& operator>>(istream& is, MyString& str)
{
	delete[] str.m_data;
	char buf[1024];

	scanf("%s, buf");
	int len;
	len = strlen(buf);
	str.m_data = new char[len + 1];
	strcpy(str.m_data, buf);

	return is;
}
posted @ 2020-08-04 10:16  NaughtyCoder  阅读(418)  评论(0)    收藏  举报