Разработка класса String

Разработайте класс String, который хранит указатель на char:
struct String {
   char *str;

Во всех задачах вы сдаете только реализацию нужных методов.

Например, для задачи "напишите конструктор по умолчанию" вы должны сдать только строки

String::String() {
  ...
}
Объявление класса String и реализацию других методов сдавать не нужно.

A: Конструкторы, деструктор

Напишите конструкторы и деструктор, который освобожает память и выводит "... destructed" и перевод на новую строку (см. пример).

Также напишите функцию Print(), которая выводит строку и затем перевод строки.

Тест Вывод
String s;
String s1 = "abc";
String s2 = s1;
String s3 = String("de");
s1.Print();
s.Print();
s2.Print();
s3.Print();
        
abc

abc
de
de desrtucted
abc desrtucted
abc desrtucted
 desrtucted
            

(Пустые строки и пробел в начале последней строки вывода обеспечиваются строкой, созданной конструктором по умолчанию)

B: Стандартный ввод и вывод

Определите операции ввода вывода:

ostream &operator<<(ostream &os, const String &s)
и
istream &operator>>(istream &is, String &s)
    
Тест Вывод
String s1, s2 = "abc";
std::cout << s2 << endl;
std::cin >> s1; // ввод defgh
std::cin >> s2; // ввод qwerty
std::cout << s1 << endl;
std::cout << s2 << endl;
std::cout << s1 << s2 << endl;
        
abc
defgh
qwerty
defgh
qwerty
defghqwerty
qwerty desrtucted
defgh desrtucted
            

С: Сложение

Определите операции сложения(склеивания) строк:

String operator+(const String &s);
String operator+(const char *s);
void operator+=(const String &s);
void operator+=(const char *s);
Тест Вывод
String s1 = "abc", s2 = "de";
String s3 = s1 + s2;
s1 += s2;
s1 += "**";
std::cout << s1 << endl << s2 << endl << s3 << endl;
        
abcde**
de
abcde
abcde desrtucted
de desrtucted
abcde** desrtucted
            

D: Сравнение на равенство

Определите внешние операции сравнения на равенство строк, чтобы можно было сравнивать String со String и String с char*.

Тест Вывод
String s1("abc");
String s2 = "abc"
String s3 = " abc";
char *str = "abc";
std::cout << (s1 == s2) << " " << (s1 != s2) << endl;
std::cout << (s1 == s3) << " " << (s1 != s3) << endl;
std::cout << (s1 == s1) << " " << (s1 != s1) << endl;
std::cout << (s1 == str) << " " << (s1 != str) << endl;
std::cout << (s1 == "abc") << " " << (s1 != "abc") << endl;
std::cout << ("abc" == s1) << " " << ("abc" != s1) << endl;
            
1 0
0 1
1 0
1 0
1 0
1 0
 abc desrtucted
abc desrtucted
abc desrtucted
            

Е: Функции поиска

Определите операции поиска в строке, чтобы можно было искать в объекте String подстроки String, char* и символы (char).
Функции должны возвращать позицию первого вхождения символа или подстроки или -1.

Тест Вывод
String s1("abcdefghijk");
String s2 = "cde";
char *str = "abc";
std::cout << s1.Find(s2) << s1.Find(str) << s1.Find("j") << s1.Find('e') << endl;
std::cout << s1.Find(String("aa")) << s1.Find("cdee") << s1.Find('z') << endl;
            
2094
-1-1-1
aa desrtucted
cde desrtucted
abcdefghijk desrtucted