У меня есть некоторый обучающий пример самодельного вектора, это не шаблон для простоты:
class UglyStringsVector {
public:
UglyStringsVector() = default;
explicit UglyStringsVector(size_t size);
UglyStringsVector(const UglyStringsVector&);
~UglyStringsVector();
std::string &operator[](size_t index);
std::string *begin();
std::string *end();
const std::string *begin() const;
const std::string *end() const;
size_t Size() const;
size_t Capacity() const;
void PushBack(std::string value);
void operator=(const UglyStringsVector &other);
private:
std::string *data = nullptr;
size_t size = 0;
size_t capacity = 0;
void ExpandIfNeeded();
};
Оператор присваивания не реализован правильно:
UglyStringsVector& UglyStringsVector::operator=(const UglyStringsVector &other) {
delete[] data;
data = new std::string[other.capacity];
size = other.size;
capacity = other.capacity;
copy(other.begin(), other.end(), begin());
return *this;
}
Как мы видим здесь, когда this == &other
( я не проверяю это условие с целью вопроса ), он удаляет свою собственную память ( конечно, это неправильно ), а затем перераспределяет новые строки в том же месте (data = new std::string[other.capacity];
) строки не инициализируются, потому что конструктор по умолчанию вызывался во время operator new[]
, а затем копировал строки в себя (copy(other.begin(), other.end(), begin());
).
Давайте представим, что потеря памяти не является проблема :-) Что-то шепчет мне, что копирование памяти в себя - неопределенное поведение, но я не уверен. Вопрос: есть ли неопределенное поведение?