[c++] 自写 MyString 类

实现了 MyString 类,同时实现了运算符重载,重载的运算符包括 <、>、==、!=、<<、>>、[] 等。

如果一个类重载了某个运算符,那么对这个类的对象进行操作的时候便会使用类重载的运算符。比如下边代码 MyString 类中重载了 <、>、==、!=、<<、>> 运算符,那么使用这些运算符操作对象的时候,便会使用对象重载之后的运算符。

(1) <、>、==、!=

① 4 个运算符重载,可以声明为友元函数,也可以声明为类的成员函数

② 声明友元函数时,形参是两个;声明为成员函数时,形参是一个

③ 对象 O1 和 O2 进行比较,成员函数是 O1.operator < (O1);友元函数是 operator < (O1, O2)

④ 声明为成员函数时,默认会带一个 this 指针,*this 是左操作数

(2) <<,>> 流操作符,需要声明为友元函数,不能声明为成员函数

(3) 不能创建新的运算符,只能重载已有的运算符

如下代码,<、>、==、!=、<<、>> 均声明为友元函数。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

class MyString {
public:
  MyString(); // 默认构造函数
  MyString(int n, char c); // 普通构造函数
  MyString(const char *str); // 普通构造函数
  MyString(const MyString &str); // 拷贝构造函数

  MyString& operator = (char *str); // 重载 =,使用字符串赋值
  MyString& operator = (const MyString &s); // 重载 =,使用对象赋值

  ~MyString(); // 析构函数

  char& operator[] (int i); // 重载 [], 实现数组操作
  const char& operator[] (int i) const; // 重载 [],事项数组操作,对象为常量

  MyString& operator += (const MyString& str); // 重载 +=,与对象相加
  MyString& operator += (const char *str); // 重载 +=,与字符串相加

  friend std::ostream& operator << (std::ostream& out, MyString& str); // 重载 <<,实现输出流
  friend std::istream& operator >> (std::istream& in, MyString& str); // 重载 >>,实现输入流

  friend bool operator < (const MyString& left, const MyString& right); // 重载 <
  friend bool operator > (const MyString& left, const MyString& right); // 重载 >
  friend bool operator == (const MyString& left, const MyString& right); // 重载 ==
  friend bool operator != (const MyString& left, const MyString& right); // 重载 !=

  char *GetData() const;

  // 对象被声明为 const,那么这个对象调用的函数也需要是 const 类型
  int Size() const;

private:
  int size;
  char *data = nullptr;
};

MyString::MyString() {
  // 默认构造函数,只包括一个字符 '\0'
  printf("MyString()\n");
  data = new char[1];
  *data = '\0';
  size = 0;
}

MyString::MyString(int n, char c) {
  printf("MyString(int n, char c), n = %d, c = %c\n", n, c);
  data = new char[n + 1];
  for (int i = 0; i < n; i++) {
    *(data + i) = c;
  }
  *(data + n) = '\0';
  size = n;
}

MyString::MyString(const char *str) {
  printf("MyString(const char *str), str = %s\n", str);
  if (str == nullptr) {
    data = new char[1];
    *data = '\0';
    size = 0;
  } else {
    data = new char[strlen(str) + 1];
    strcpy(data, str);
    size = strlen(str);
  }
}

MyString::MyString(const MyString &str) {
  printf("MyString(const MyString &str), str = %s\n",  str.GetData());
  data = new char[str.size + 1];
  strcpy(data, str.data);
  size = str.size;
}

MyString& MyString::operator = (char *str) {
  printf("operator =, MyString = char *, str = %s\n", str);
  if (data != nullptr) {
    delete []data;
  }
  data = new char[strlen(str) +1];
  strcpy(data, str);
  return *this;
}

MyString&MyString::operator = (const MyString& str) {
  printf("operator =, MyString = MyString, str = %s\n", str.GetData());
  if (this == &str) {
    return *this;
  }

  if (data != nullptr) {
    delete []data;
  }

  data = new char[str.size + 1];
  strcpy(data, str.data);
  return *this;
}

MyString::~MyString() {
  if (data != nullptr) {
    delete []data;
    data = nullptr;
    size = 0;
  }
}

char& MyString::operator [](int i) {
  return data[i];
}

const char& MyString::operator[] (int i) const {
  printf("operator [], const\n");
  return data[i];
}

MyString& MyString::operator +=(const MyString& s) {
  printf("operator += MyString, str = %s\n", s.GetData());
  int length = size + s.size + 1;
  char *tmp = data;
  data = new char[length];
  size = length - 1;
  strcpy(data, tmp);
  strcat(data, s.data);
  delete []tmp;
  return *this;
}

MyString& MyString::operator += (const char *str) {
  printf("operator += char *, str = %s\n", str);
  if (str == nullptr) {
    return *this;
  }

  int length = size + strlen(str) + 1;
  char *tmp = data;
  data = new char[length];
  size = length - 1;
  strcpy(data, tmp);
  strcat(data, str);
  delete []tmp;
  return *this;
}

int MyString::Size() const {
  return size;
}

char* MyString::GetData() const {
  return data;
}

std::ostream& operator << (std::ostream &out, MyString &str) {
  for (int i = 0; i < str.Size(); i++) {
    out << str[i] << " ";
  }
  return out;
}

std::istream& operator >> (std::istream& in, MyString& str) {
  char p[50];
  in.getline(p, 50);
  str = p;
  return in;
}

bool operator < (const MyString& left, const MyString& right) {
  int i = 0;
  while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {
    i++;
  }

  if (left[i] < right[i]) {
    return true;
  }
  return false;
}

bool operator > (const MyString& left, const MyString& right) {
  int i = 0;
  while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {
    i++;
  }

  if (left[i] > right[i]) {
    return true;
  }
  return false;
}

bool operator == (const MyString& left, const MyString& right) {
  if (left.Size() != right.Size()) {
    return false;
  }

  int i = 0;
  while (left[i] != '\0' && right[i] != '\0') {
    if (left[i] != right[i]) {
      return false;
    }
    i++;
  }

  return true;
}

bool operator != (const MyString& left, const MyString& right) {
  if (left.Size() != right.Size()) {
    return true;
  }

  int i = 0;
  while (left[i] != '\0' && right[i] != '\0') {
    if (left[i] != right[i]) {
      return true;
    }
    i++;
  }

  return false;
}

int main() {
  printf("构造 --------------------------------\n");
  MyString s1(3, 'a'); // 默认构造函数
  MyString s2(s1); // 拷贝构造函数
  MyString s3("abcdefghijklmn"); // 通过 char * 来构造函数
  MyString s4; // 空的字符串

  printf("\noperator << --------------------------------\n");
  std::cout << "s1: " << s1 << std::endl; // 输出字符串,使用重载的运算符 <<
  std::cout << "s2: " << s2 << std::endl;
  std::cout << "s3: " << s3 << std::endl;
  std::cout << "s4: " << s4 << std::endl;

  printf("\noperator = --------------------------------\n");
  s4 = s3; // 字符串赋值,使用字符串对象赋值
  std::cout << "s4: " << s4 << std::endl;
  s4 = "abcd"; // 使用 char * 赋值
  std::cout << "s4: " << s4 << std::endl;

  std::cout << "s4[2] = " << s4[2] << std::endl;

  printf("\noperator += --------------------------------\n");
  s4 += "mmmm";
  std::cout << "s4: " << s4 << std::endl;
  s4 += s2;
  std::cout << "s4: " << s4 << std::endl;

  printf("\noperator >> --------------------------------\n");
  std::cin >> s2;
  std::cout << "s2: " << s2 << std::endl;

  printf("\n<, >, ==, != --------------------------------\n");
  MyString t1 = "1234";
  MyString t2 = "1234";

  MyString t3 = "12345";
  MyString t4 = "12335";
  std::cout << "t1 == t2 ? " << (t1 == t2) << std::endl;
  std::cout << "t1 < t3 ? " << (t1 < t3) << std::endl;
  std::cout << "t1 > t4 ?  " << (t1 > t4) << std::endl;
  std::cout << "t1 != t4 ? " << (t1 != t4) << std::endl;
  return 0;
}

如下代码,<、>、==、!= 声明为成员函数,当成员函数和友元函数同时存在时,优先选用成员函数。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>

class MyString {
public:
  MyString(); // 默认构造函数
  MyString(int n, char c); // 普通构造函数
  MyString(const char *str); // 普通构造函数
  MyString(const MyString &str); // 拷贝构造函数

  MyString& operator = (char *str); // 重载 =,使用字符串赋值
  MyString& operator = (const MyString &s); // 重载 =,使用对象赋值

  ~MyString(); // 析构函数

  char& operator[] (int i); // 重载 [], 实现数组操作
  const char& operator[] (int i) const; // 重载 [],事项数组操作,对象为常量

  MyString& operator += (const MyString& str); // 重载 +=,与对象相加
  MyString& operator += (const char *str); // 重载 +=,与字符串相加

  friend std::ostream& operator << (std::ostream& out, MyString& str); // 重载 <<,实现输出流
  friend std::istream& operator >> (std::istream& in, MyString& str); // 重载 >>,实现输入流

  friend bool operator < (const MyString& left, const MyString& right); // 重载 <
  friend bool operator > (const MyString& left, const MyString& right); // 重载 >
  friend bool operator == (const MyString& left, const MyString& right); // 重载 ==
  friend bool operator != (const MyString& left, const MyString& right); // 重载 !=

  bool operator < (const MyString& str); // 重载 <
  bool operator > (const MyString& str); // 重载 >
  bool operator == (const MyString& str); // 重载 ==
  bool operator != (const MyString& str); // 重载 !=

  char *GetData() const;

  // 对象被声明为 const,那么这个对象调用的函数也需要是 const 类型
  int Size() const;

private:
  int size;
  char *data = nullptr;
};

MyString::MyString() {
  // 默认构造函数,只包括一个字符 '\0'
  printf("MyString()\n");
  data = new char[1];
  *data = '\0';
  size = 0;
}

MyString::MyString(int n, char c) {
  printf("MyString(int n, char c), n = %d, c = %c\n", n, c);
  data = new char[n + 1];
  for (int i = 0; i < n; i++) {
    *(data + i) = c;
  }
  *(data + n) = '\0';
  size = n;
}

MyString::MyString(const char *str) {
  printf("MyString(const char *str), str = %s\n", str);
  if (str == nullptr) {
    data = new char[1];
    *data = '\0';
    size = 0;
  } else {
    data = new char[strlen(str) + 1];
    strcpy(data, str);
    size = strlen(str);
  }
}

MyString::MyString(const MyString &str) {
  printf("MyString(const MyString &str), str = %s\n",  str.GetData());
  data = new char[str.size + 1];
  strcpy(data, str.data);
  size = str.size;
}

MyString& MyString::operator = (char *str) {
  printf("operator =, MyString = char *, str = %s\n", str);
  if (data != nullptr) {
    delete []data;
  }
  data = new char[strlen(str) +1];
  strcpy(data, str);
  return *this;
}

MyString&MyString::operator = (const MyString& str) {
  printf("operator =, MyString = MyString, str = %s\n", str.GetData());
  if (this == &str) {
    return *this;
  }

  if (data != nullptr) {
    delete []data;
  }

  data = new char[str.size + 1];
  strcpy(data, str.data);
  return *this;
}

MyString::~MyString() {
  if (data != nullptr) {
    delete []data;
    data = nullptr;
    size = 0;
  }
}

char& MyString::operator [](int i) {
  return data[i];
}

const char& MyString::operator[] (int i) const {
  return data[i];
}

MyString& MyString::operator +=(const MyString& s) {
  printf("operator += MyString, str = %s\n", s.GetData());
  int length = size + s.size + 1;
  char *tmp = data;
  data = new char[length];
  size = length - 1;
  strcpy(data, tmp);
  strcat(data, s.data);
  delete []tmp;
  return *this;
}

MyString& MyString::operator += (const char *str) {
  printf("operator += char *, str = %s\n", str);
  if (str == nullptr) {
    return *this;
  }

  int length = size + strlen(str) + 1;
  char *tmp = data;
  data = new char[length];
  size = length - 1;
  strcpy(data, tmp);
  strcat(data, str);
  delete []tmp;
  return *this;
}

int MyString::Size() const {
  return size;
}

char* MyString::GetData() const {
  return data;
}

std::ostream& operator << (std::ostream &out, MyString &str) {
  for (int i = 0; i < str.Size(); i++) {
    out << str[i] << " ";
  }
  return out;
}

std::istream& operator >> (std::istream& in, MyString& str) {
  char p[50];
  in.getline(p, 50);
  str = p;
  return in;
}

bool operator < (const MyString& left, const MyString& right) {
  int i = 0;
  while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {
    i++;
  }

  if (left[i] < right[i]) {
    return true;
  }
  return false;
}

bool operator > (const MyString& left, const MyString& right) {
  int i = 0;
  while (left[i] != '\0' && right[i] != '\0' && left[i] == right[i]) {
    i++;
  }

  if (left[i] > right[i]) {
    return true;
  }
  return false;
}

bool operator == (const MyString& left, const MyString& right) {
  if (left.Size() != right.Size()) {
    return false;
  }

  int i = 0;
  while (left[i] != '\0' && right[i] != '\0') {
    if (left[i] != right[i]) {
      return false;
    }
    i++;
  }

  return true;
}

bool operator != (const MyString& left, const MyString& right) {
  if (left.Size() != right.Size()) {
    return true;
  }

  int i = 0;
  while (left[i] != '\0' && right[i] != '\0') {
    if (left[i] != right[i]) {
      return true;
    }
    i++;
  }

  return false;
}

//
bool MyString::operator < (const MyString& str) {
  int i = 0;
  while (data[i] != '\0' && str[i] != '\0' && data[i] == str[i]) {
    i++;
  }

  if (data[i] < str[i]) {
    return true;
  }
  return false;
}

bool MyString::operator > (const MyString& str) {
  int i = 0;
  while (data[i] != '\0' && str[i] != '\0' && data[i] == str[i]) {
    i++;
  }

  if (data[i] > str[i]) {
    return true;
  }
  return false;
}

bool MyString::operator == (const MyString& str) {
  if (size != str.Size()) {
    return false;
  }

  int i = 0;
  while (data[i] != '\0' && str[i] != '\0') {
    if (data[i] != str[i]) {
      return false;
    }
    i++;
  }

  return true;
}

bool MyString::operator != (const MyString& str) {
  if (size != str.Size()) {
    return true;
  }

  int i = 0;
  while (data[i] != '\0' && str[i] != '\0') {
    if (data[i] != str[i]) {
      return true;
    }
    i++;
  }

  return false;
}

int main() {
  printf("构造 --------------------------------\n");
  MyString s1(3, 'a'); // 默认构造函数
  MyString s2(s1); // 拷贝构造函数
  MyString s3("abcdefghijklmn"); // 通过 char * 来构造函数
  MyString s4; // 空的字符串

  printf("\noperator << --------------------------------\n");
  std::cout << "s1: " << s1 << std::endl; // 输出字符串,使用重载的运算符 <<
  std::cout << "s2: " << s2 << std::endl;
  std::cout << "s3: " << s3 << std::endl;
  std::cout << "s4: " << s4 << std::endl;

  printf("\noperator = --------------------------------\n");
  s4 = s3; // 字符串赋值,使用字符串对象赋值
  std::cout << "s4: " << s4 << std::endl;
  s4 = "abcd"; // 使用 char * 赋值
  std::cout << "s4: " << s4 << std::endl;

  std::cout << "s4[2] = " << s4[2] << std::endl;

  printf("\noperator += --------------------------------\n");
  s4 += "mmmm";
  std::cout << "s4: " << s4 << std::endl;
  s4 += s2;
  std::cout << "s4: " << s4 << std::endl;

  printf("\noperator >> --------------------------------\n");
  std::cin >> s2;
  std::cout << "s2: " << s2 << std::endl;

  printf("\n<, >, ==, != --------------------------------\n");
  MyString t1 = "1234";
  MyString t2 = "1234";

  MyString t3 = "12345";
  MyString t4 = "12335";
  std::cout << "t1 == t2 ? " << (t1 == t2) << std::endl;
  std::cout << "t1 < t3 ? " << (t1 < t3) << std::endl;
  std::cout << "t1 > t4 ?  " << (t1 > t4) << std::endl;
  std::cout << "t1 != t4 ? " << (t1 != t4) << std::endl;
  return 0;
}
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值