Napisałem podobną klasę.
Użycie:
String test1 = "Hello";
String test2 = getSpaceOrNewline(true);
test1 += test2;
String test3 = test1 + "world!";
String test4;
test4 = getSpaceOrNewline(false);
test2 = test4;
std::cout << test3.getCString() << test2.getCString();
Klasa nie jest skomplikowana, ba, jest bardzo prosta z perspektywy C++. Ma to, co każda klasa, która sama zarządza pamięcią powinna mieć, czyli co najmniej trzy konstruktory oraz dwa operatory przypisania i każdy z nich jest użyty w kodzie powyżej ;).
move constructor
i move assignment operator
można wywalić, jeżeli nie chcemy korzystać z C++11, kod też będzie działać.
Wynik (debug):
Visual Leak Detector Version 2.2.3 installed.
conversion construtor
conversion construtor
move construtor
conversion construtor
copy construtor
move construtor
default construtor
conversion construtor
move construtor
move assignment operator
copy construtor
copy assignment operator
Hello world!
No memory leaks detected.
Visual Leak Detector is now exiting.
Cały kod:
#include <vld.h>
#include <cstring>
#include <iostream>
// NULL-terminated C-style string
class String
{
private:
char* _chars;
size_t _length;
public:
~String()
{
delete _chars;
}
// default constructor
String() : _chars(NULL), _length(0)
{
std::cout << "default construtor\n";
}
// conversion constructor
String(const char* cstring)
{
_length = strlen(cstring);
_chars = new char[_length + 1];
strcpy(_chars, cstring);
std::cout << "conversion construtor\n";
}
// copy construtor
String(const String& other)
{
_length = other.getLength();
_chars = new char[_length + 1];
strcpy(_chars, other.getCString());
std::cout << "copy construtor\n";
}
// move constructor
String(String&& other) : _chars(NULL), _length(0)
{
swap(*this, other);
std::cout << "move construtor\n";
}
// copy assignment operator
String& operator=(const String& other)
{
String copy(other);
swap(*this, copy);
std::cout << "copy assignment operator\n";
return *this;
}
// move assignment operator
String& operator=(String&& other)
{
swap(*this, other);
std::cout << "move assignment operator\n";
return *this;
}
friend void swap(String& first, String& second)
{
std::swap(first._length, second._length);
std::swap(first._chars, second._chars);
}
const char* getCString() const
{
return _chars;
}
size_t getLength() const
{
return _length;
}
String& operator+=(const String& another)
{
_length += another.getLength();
char* buffer = new char[_length + 1];
strcpy(buffer, _chars);
strcat(buffer, another.getCString());
delete _chars;
_chars = buffer;
return *this;
}
String operator+(const String& another)
{
String result(*this);
result += another;
return result;
}
};
String getSpaceOrNewline(bool choice)
{
String ret = choice ? " " : "\n"; return ret;
}
int main()
{
String test1 = "Hello";
String test2 = getSpaceOrNewline(true);
test1 += test2;
String test3 = test1 + "world!";
String test4;
test4 = getSpaceOrNewline(false);
test2 = test4;
std::cout << test3.getCString() << test2.getCString();
return 0;
}