#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <Windows.h>
#include <map>
using namespace std;
class String {
private:
unsigned int length;
char* cstring;
void clean() {
if (cstring) {
delete[] cstring;
}
length = 0;
}
public:
String(const char* str) : length(strlen(str)), cstring(new char[length + 1]) {
strcpy(cstring, str);
cout << "ctor" << endl;
}
String() : String("") {
}
String(int size, char symbol) : cstring(new char[size + 1]), length(size) {
if (size) {
memset(cstring, symbol, size);
cstring[size] = '\0';
}
}
String(const String& other) {
length = other.length;
cstring = new char[length + 1];
strcpy(cstring, other.cstring);
}
String& operator=(const String& other) {
cout << "String& operator=(const String& other)" << endl;
if (this == &other)
return *this;
clean();
length = other.length;
cstring = new char[length + 1];
strcpy(cstring, other.cstring);
return *this;
}
String(String&& other) noexcept {
length = other.length;
cstring = other.cstring;
other.cstring = nullptr;
}
String& operator=(String&& other) noexcept {
cout << "=&&" << endl;
if (this == &other)
return *this;
clean();
length = other.length;
cstring = other.cstring;
other.cstring = nullptr;
return *this;
}
String& operator +=(String const& other) {
cout << "=+" << endl;
if (other.length) {
unsigned int size = length + other.length;
char* buff = new char[size + 1];
strcpy(buff, cstring);
strcat(buff, other.cstring);
clean();
cstring = buff;
length = size;
buff = nullptr;
return *this;
}
}
~String() {
clean();
cout << "dtor" << endl;
}
inline bool isEmpty() { return length == 0; }
inline unsigned int getLength() { return length; }
inline const char* c_str() const { return cstring; }
bool operator==(const String& t) const {
return length == t.length && strcmp(cstring, t.cstring) == 0;
}
bool operator !=(const String& t) const {
return !(operator==(t));
}
char& operator[](const int i) {
return cstring[i];
}
void stringLow() {
for (int j = 0; j < length; ++j)
cstring[j] = (char)(tolower(cstring[j]));
}
void stringUp() {
for (int j = 0; j < length; ++j)
cstring[j] = (char)(toupper(cstring[j]));
}
void reverse() {
for (int i = 0; i < length / 2; i++) {
swap(cstring[i], cstring[length - i - 1]);
}
}
friend String operator+(String l, const String& r) {
return l += r;
}
friend istream& operator >>(istream& is, String& obj) {
char* buff = new char[99];
memset(&buff[0], 0, sizeof(buff));
is >> buff;
obj = String(buff);
delete[] buff;
return is;
}
friend ostream& operator <<(ostream& os, const String& obj) {
os << obj.cstring;
return os;
}
};
int main() {
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
String var("Люблю ");
String var2("много пива");
String var3 = var + var2;
}
好吧,我会做这样的事情......
主要是明确定义类不变量。然后零长度可以对应空字符串和
nullptr. 长度本身仅对足够大的字符串长度有意义,否则它不会进行太多优化。不需要相同的
clean(),因为在类中不需要将长度归零的情况下调用它。是的,它delete可以与 一起使用nullptr,不需要检查。一般来说,如果不清楚为什么我做错了什么,看看是什么以及如何做 - 问。
是的,以防万一:不要意外更改数据成员的声明顺序,您的构造函数依赖它。还有一件事——在声明一个类时,你不应该使用
using namespace,把它留给用户。在一个类中,最好使用完全限定名。