自制的丑陋矢量

Self-made ugly vector

我有一些自制向量的训练示例,为了简单起见,它不是模板:

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());).

让我们想象一下,失去记忆不是问题:-) 有人对我耳语说将内存复制到自身是未定义的行为,但我不确定。 问题:有没有未定义的行为?

假设data是一个有效的指针或nullptr,那么实际上根本就没有UB。

使用 new std::string[other.capacity] 您可以创建 "array" 个 default-initialized std::string 个对象。默认初始化(基本上默认构造)std::string 是一个有效但空的字符串。

然后您将这个空字符串数组复制到自身,这很好。


关于自拷贝,类似

int a = 0;
a = a;

这很奇怪但很好。

没有任何未定义的行为。你只需删除数据指针指向的内存部分,然后重新分配一个新数组并将其分配给数据。