#include <iostream>
#include <cstring>
#include <utility>
#include <vector>
class MyString {
private:
char* data_;
size_t len_;
public:
MyString() : data_(nullptr), len_(0) {
data_ = new char[1];
data_[0] = '\0';
std::cout << "[Default Constructor] Created empty string\n";
}
MyString(const char* str) : len_(std::strlen(str)) {
data_ = new char[len_ + 1];
std::strcpy(data_, str);
std::cout << "[Constructor] Created: " << data_ << "\n";
}
MyString(const MyString& other) : len_(other.len_) {
data_ = new char[len_ + 1];
std::strcpy(data_, other.data_);
std::cout << "[Copy Constructor] Deep copy of: " << other.data_ << "\n";
}
MyString(MyString&& other) noexcept : data_(other.data_), len_(other.len_) {
other.data_ = nullptr;
other.len_ = 0;
std::cout << "[Move Constructor] Moved from: " << (data_ ? data_ : "nullptr") << "\n";
}
MyString& operator=(const MyString& other) {
if (this != &other) {
std::cout << "[Copy Assignment] Deep copy of: " << other.data_ << "\n";
delete[] data_;
len_ = other.len_;
data_ = new char[len_ + 1];
std::strcpy(data_, other.data_);
}
return *this;
}
MyString& operator=(MyString&& other) noexcept {
if (this != &other) {
std::cout << "[Move Assignment] Moving from: " << (other.data_ ? other.data_ : "nullptr") << "\n";
delete[] data_;
data_ = other.data_;
len_ = other.len_;
other.data_ = nullptr;
other.len_ = 0;
}
return *this;
}
~MyString() {
std::cout << "[Destructor] Destroyed string: " << (data_ ? data_ : "(null)") << "\n";
delete[] data_;
}
const char* c_str() const {
return data_ ? data_ : "";
}
size_t length() const {
return len_;
}
MyString operator+(const MyString& other) const {
size_t new_len = len_ + other.len_;
char* new_data = new char[new_len + 1];
std::strcpy(new_data, data_);
std::strcat(new_data, other.data_);
MyString result;
delete[] result.data_;
result.data_ = new_data;
result.len_ = new_len;
std::cout << "[Operator+] Created temporary: " << result.data_ << "\n";
return result;
}
};
template<typename T, typename... Args>
T createObject(Args&&... args) {
return T(std::forward<Args>(args)...);
}
void takeOwnership(MyString&& str) {
MyString local = std::move(str);
std::cout << "[takeOwnership] Now owning: " << local.c_str() << "\n";
}
int main() {
std::cout << "========== 1. Basic Construction and Copy ==========\n";
MyString a("Hello");
MyString b = a;
MyString c;
c = a;
std::cout << "\n========== 2. Move Semantics Demonstration ==========\n";
MyString d = std::move(a);
std::cout << "After move, a is now: " << a.c_str() << " (empty)\n";
MyString e("World");
MyString f;
f = std::move(e);
std::cout << "After move, e is now: " << e.c_str() << " (empty)\n";
std::cout << "\n========== 3. Receiving Rvalue Reference in Function ==========\n";
takeOwnership(MyString("Temporary"));
MyString g("Another");
takeOwnership(std::move(g));
std::cout << "\n========== 4. Perfect Forwarding to Create Objects ==========\n";
MyString original("Original");
auto copy = createObject<MyString>(original);
auto moved = createObject<MyString>(MyString("Temporary"));
auto literal = createObject<MyString>("Literal");
std::cout << "\n========== 5. Move Semantics in Containers (Performance Optimization) ==========\n";
std::vector<MyString> vec;
vec.reserve(3);
std::cout << "Pushing temporary objects:\n";
vec.push_back(MyString("First"));
vec.push_back(MyString("Second"));
vec.push_back(MyString("Third"));
std::cout << "\nPushing existing object with std::move:\n";
MyString existing("Existing");
vec.push_back(std::move(existing));
std::cout << "\nContents of vector:\n";
for (const auto& item : vec) {
std::cout << " - " << item.c_str() << "\n";
}
std::cout << "\n========== 6. Operator Returns Temporary Object ==========\n";
MyString hello("Hello ");
MyString world("World");
MyString helloWorld = hello + world;
std::cout << "Result of concatenation: " << helloWorld.c_str() << "\n";
std::cout << "\n========== Program End, All Objects Will Be Destructed ==========\n";
return 0;
}