我是靠谱客的博主 独特绿草,最近开发中收集的这篇文章主要介绍String 类的封装C++,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

实验代码

String.h

String.cpp

main.cpp主函数

实验总结

测试代码


主要任务:

创建一个String来进行以下测试

int main()
{
    String s1("help!"), s2("Good!"), s3(s2), s4, s5;
    cout << "s1=" << s1 << endl;//s1=help!
    s3 = "help!";
    cout << "s3=" << s3 << endl;//s3=help!
    s3 = s2;
    cout << "s3=" << s3 << endl;//s3=Good!
    s3 += s2;
    cout << "s3=" << s3 << endl;//s3=Good!Good!
    cin >> s4;//输入jobs
    cout << "s4=" << s4 << endl;//s4=jobs
    s5 = s3+s4;
    cout << "s5=" << s5 << endl;//s5=Good!Good!jobs
    s5 = 'g';
    cout << "s5=" << s5 << endl;//s5=g
    cout << "strlen(s5)=" << s5.Length() << endl;//strlen(s5)=1
    cout << boolalpha << (s3 == s1) << endl;//s3=Good!Good!和s1=help! 返回false
    cout << boolalpha << (s3 < s1) << endl;//成立返回true
    return 0;
}

实验代码

String.h

#pragma once
#include<iostream>
using namespace std;
class String
{
public:
friend ostream& operator<<(ostream& os, String& c);
friend istream& operator>>(istream& is, String& c);
String();
String(const char* s);
//复制构造
String(String& ss);
//移动构造函数
String(String&& s)noexcept;
//返回字符串长度
int Length();
//重载=,传入字符串
String& operator =(const char*c);
//重载=,深复制
String& operator =(String& c);
//重载= 移动构造
String& operator=(String&& c);
//重载= 传入单个字符
String& operator=(char c);
//重载+= 连接字符串
String& operator+=(String& c);
//重载+
String operator + (String & c);
//重载[]
char operator[](int i);
//重载==
bool operator==(String& c);
//重载<
bool operator<(String& c);
~String()
{
if (this->m_str != NULL)
{
delete m_str;
m_str = NULL;
}
}
private:
char* m_str;
int m_size;//含有的长度
};

String.cpp

#include"String.h"
String::String():m_size(0)
{
this->m_str = new char();
}
//有参构造
String::String(const char* s ): m_size(strlen(s))
{
this->m_str = new char[this->m_size+1];
//strcpy_s(m_str, m_size+1, s);
strcpy(m_str, s);
}
//复制构造
String::String(String& ss):m_size(ss.Length())
{
this->m_str = new char[m_size+1];
//strcpy_s(m_str, m_size+1, ss.m_str);
strcpy(m_str, ss.m_str);
}
//移动构造函数
String::String(String&& s)noexcept
{
this->m_size = s.m_size;
this->m_str = new char[this->m_size + 1];
strcpy(this->m_str, s.m_str);
}
//重载[]
char String::operator[](int i)
{
return this->m_str[i];
}
//重载==
bool String::operator==(String& c)
{
if (strcmp(this->m_str, c.m_str))//不相等时,返回非0,进入if
return false;
return true;
}
//重载<
bool String::operator<(String& c)
{
if (strcmp(this->m_str, c.m_str) < 0)
return true;
return false;
}
//赋值传入字符串
String& String::operator=(const char* c)
{
this->m_size = strlen(c);
this->m_str = new char[this->m_size + 1];
strcpy(this->m_str, c);
return *this;
}
//重载=,深复制
String& String::operator =(String& c)
{
this->m_size = c.Length();
this->m_str = new char[m_size+1];
strcpy(this->m_str, c.m_str);
return *this;
}
//重载= 移动构造
String& String::operator=(String&& c)
{
this->m_size = c.Length();
this->m_str = new char[m_size + 1];
strcpy(this->m_str, c.m_str);
return *this;
}
//重载= 传入单个字符
String& String::operator=(char c)
{
this->m_size = 1;
this->m_str = new char[2];
this->m_str[0] = c;
this->m_str[1] = '';
return *this;
}
//重载+= 连接字符串
String& String::operator+=(String& c)
{
this->m_size += c.m_size;//更新空间值
char* temp= strcat(this->m_str, c.m_str);//连接后赋值临时变量
this->m_str = new char[this->m_size + 1];//开辟新空间
strcpy(this->m_str, temp);//赋值
return *this;
}
//重载+
String String::operator + (String& c)
{
String temp;
temp.m_size = this->m_size + c.m_size;
temp.m_str = new char[temp.m_size + 1];
strcpy(temp.m_str, this->m_str);
strcat(temp.m_str, c.m_str);
return temp;
}
//返回字符串长度
int String::Length()
{
return this->m_size;
}
//重载<<
ostream& operator<<(ostream &os, String& c)
{
os << c.m_str;
return os;
}
istream& operator>>(istream& is, String& c)
{
/*第一想法(错),创建一个String s;
时, 由于默认构造,分配空间0,因此后输入的话空间不足,输出会报错,无法分配*/
//is>>c.m_str;
// return is;
/*第二想法(对),可以先创建一个对象,空间给足够,输入值后,调整指针和空间大小后赋值给c,但缺点是
创建一个比较大的对象空间开销太大,导致浪费*/
//String temp;
//temp.m_str = new char[1000];
//is >> temp.m_str;
//temp.m_size = strlen(temp.m_str);
//c = temp;
/*思考了一下,可以先输入字符串,创建临时字符串指针存储,c的空间为temp的大小,
开辟空间为size+1,之后把这个临时的字符串赋值给c,这样开销最小,动态分配*/
is >> c.m_str;
const char* temp = c.m_str;
c.m_size = strlen(temp);
c.m_str = new char[c.m_size + 1];
strcpy(c.m_str,temp);
return is;
}

main.cpp主函数

#include"String.h"
int main()
{
String s1("help!"), s2("Good!"), s3(s2), s4, s5;
cout << "s1=" << s1 << endl;//s1=help!
s3 = "help!";
cout << "s3=" << s3 << endl;//s3=help!
s3 = s2;
cout << "s3=" << s3 << endl;//s3=Good!
s3 += s2;
cout << "s3=" << s3 << endl;//s3=Good!Good!
cin >> s4;//jobs
cout << "s4=" << s4 << endl;//s4=jobs
s5 = s3+s4;
cout << "s5=" << s5 << endl;//s5=Good!Good!jobs
s5 = 'g';
cout << "s5=" << s5 << endl;//s5=g
cout << "strlen(s5)=" << s5.Length() << endl;//strlen(s5)=1
cout << boolalpha << (s3 == s1) << endl;//s3=Good!Good!和s1=help! 返回false
cout << boolalpha << (s3 < s1) << endl;//成立返回true
return 0;
}

实验总结

总结一下,容易出现内存分配不足问题,重载>>时动态分配,由于内部存在指针,所以析构时会清除指针,要进行深复制(防止堆区的数据被释放两次,这个会报错),重载的时候要注意时返回String还是String&,很有影响,String& 返回本身因此可以链式操作,String则不可以,然后注意重载各种操作符号即可完成此测试。

测试代码

s4输入jobs截图如下:

最后

以上就是独特绿草为你收集整理的String 类的封装C++的全部内容,希望文章能够帮你解决String 类的封装C++所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部