文章目录
1、
实现string类的接口,并完成测试,要求利用深拷贝和深赋值实现
MyString.h
#pragma once
#include<iostream>
class MyString {
private:char* data;//储存字符串内容
public://默认构造函数MyString(const char* str = nullptr);////拷贝构造函数(深拷贝)MyString(const MyString& other);//析构函数~MyString();// 赋值运算符重载MyString& operator=(const MyString& other);//获取字符串长度int length() const;//获取c风格字符串const char* c_str() const;//重载[]运算符char& operator[](int index);//重载==操作符bool operator==(const MyString& other) const;////打印字符串void print() const;// 重载 << 操作符(友元函数)friend std::ostream& operator<<(std::ostream& os, const MyString& str);
};
MyString.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"MyString.h"
#include<cstring>
MyString::MyString(const char* str )
{if (str == nullptr){ data = new char[1];data[0] = '\0';}else{data = new char[strlen(str)+1];strcpy(data, str);}
}MyString::MyString(const MyString& other) {// strcpy(data, other.data); // 把 other 的字符串内容复制过来//注意:将对象 other 中的字符串内容(other.data)完整地复制到当前对象的 data 成员变量中。data = new char[strlen(other.data)+1];strcpy(data, other.data);
}MyString::~MyString()
{delete[] data;
}MyString& MyString:: operator=(const MyString& other)
{if (this == &other) return *this;//如果this和other的地址相同,返回other这个值MyString::~MyString();data = new char[strlen(other.data) + 1];strcpy(data, other.data);return *this;
}
void MyString::print() const
{std::cout << data ;
}//获取字符串长度
int MyString ::length() const
{return static_cast<int>(strlen(data));
}//获取c风格字符串
const char* MyString::c_str() const
{return data;
}
//重载[]运算符
char& MyString::operator[](int index)
{if (index<0 || index>strlen(data)){throw std::out_of_range("Index out of range");}return data[index];
}
//重载==操作符
bool MyString::operator==(const MyString& other) const
{return strcmp(data, other.data)==0;
}// 重载 << 操作符(友元函数)
std::ostream& operator<<(std::ostream& os, const MyString& str)
{os << str.data;return os;
}
test.cpp
#define _CRT_SECURE_NO_WARNINGS 1
#include"MyString.h"
int main()
{////默认构造函数MyString s1("aaaa");std::cout << "s1";s1.print();std::cout << std::endl;////拷贝构造函数(深拷贝)MyString s2 = s1;std::cout << "s2 after copy ";s2.print();std::cout << std::endl;// 修改原对象不应影响拷贝对象s1[0] = 'h'; // 使用 [] 运算符修改 s1 的第一个字符std::cout << "Modified s1: " << s1 << std::endl;std::cout << "s2 remains unchanged: " << s2 << std::endl;// 测试赋值操作符MyString s3;s3 = s1;std::cout << "s3 after assignment: " << s3 << std::endl;// 测试比较操作符if (s1 == s3) {std::cout << "s1 and s3 are equal." << std::endl;}// 测试长度std::cout << "Length of s1: " << s1.length() << std::endl;return 0;
}
遇到的问题:
实现MyString
1、data = new char[空间+1](必须是data)
2、strcpy(目标,旧文件)
3、 析构 delete[] data;
4、 strcpy(data, other.data); // 把 other 的字符串内容复制过来
注意:将对象 other 中的字符串内容(other.data)完整地复制到当前对象的 data 成员变量中。
5、return static_cast(strlen(data));
static_cast 的作用
static_cast 是 C++ 的显式类型转换运算符,用于在编译时进行安全的类型转换。
这里将 size_t(无符号)转换为 int(有符号),可能出于以下原因:
兼容性:某些旧代码或接口可能要求 int 类型的长度。
明确意图:开发者明确知道字符串长度不会超过 INT_MAX(int 的最大值),并希望消除编译器关于有符号/无符号比较的警告。
6、const char* MyString::c_str() const {
return data;
}
返回类型 const char*
返回一个指向常量字符(const char)的指针,意味着调用者不能通过该指针修改字符串内容。
这是为了保护 MyString 内部数据(data)不被意外修改。
函数名 c_str()
模仿 C++ 标准库 std::string 的接口,用于返回一个 C 风格字符串(以 \0 结尾的字符数组)。
通常用于与其他 C 风格字符串接口兼容(如 printf、文件操作等)。
const 修饰符(函数末尾)
表示这是一个常量成员函数,即该函数不会修改类的任何成员变量(除非成员被声明为 mutable)。
允许在 const MyString 对象上调用此函数。
7、throw std::out_of_range(“Index out of range”); 的作用是 抛出一个 C++ 标准库中的 std::out_of_range 异常,通常用于表示某个索引(下标)超出了有效范围。
8、 os << str.data; // 将 MyString 内部的字符数据(data)输出到流 os
return os; // 返回流对象,支持链式调用(如 cout << a << b)
9.友元函数// 重载 << 操作符(友元函数)
friend std::ostream& operator<<(std::ostream& os, const MyString& str);
以上就是今天练习的内容。。