自制的丑陋矢量
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;
这很奇怪但很好。
没有任何未定义的行为。你只需删除数据指针指向的内存部分,然后重新分配一个新数组并将其分配给数据。
我有一些自制向量的训练示例,为了简单起见,它不是模板:
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;
这很奇怪但很好。
没有任何未定义的行为。你只需删除数据指针指向的内存部分,然后重新分配一个新数组并将其分配给数据。