你问到了关于向量的问题,那么这里是类
tbx::Vector
。我把它写成了一个练习。它的设计遵循了
Arthur O'Dwyer在 CppCon 2019 上的演讲。可以看一下标题为
回到基础:RAII和零规则的 YouTube 视频。
为了更加专注于你所问的复制语义,我只包括了五个“特殊”的成员函数,还有几个构造函数以及成员函数
reserve
和
swap
。尽管类
Vector
实现了几乎所有
std::vector
的接口,但其他函数在这里没有显示出来。
我留下了一些钩子,在运算符
new
尝试分配失败时,你可以插入所需的代码。
这并不是用来进行生产的代码。首先,为什么要重复造轮子呢?其次,有很多优化被省略了。第三,某些功能被省略了,例如,我没有提供完整的构造函数或对分配器的支持。
template< typename T >
class Vector
{
public:
using value_type = T;
using size_type = std::size_t;
using iterator = value_type*;
using const_iterator = value_type const*;
private:
value_type* data_{ nullptr };
size_type capacity_{};
size_type size_{};
enum : size_type { zero, one };
public:
Vector() noexcept
= default;
explicit Vector(size_type const size)
: data_{ nullptr }, capacity_{ size }, size_{ size }
{
if (zero < size)
{
try { data_ = new value_type[size]; }
catch (std::bad_alloc const&) { throw; }
}
}
Vector (Vector const& that)
: data_{ nullptr }
, capacity_{ that.size_ }
, size_{ that.size_ }
{
if (that.size_ != zero)
{
try { data_ = new value_type[that.size_]; }
catch (std::bad_alloc const&) { throw; }
std::copy(that.data_, that.data_ + size_, data_);
}
}
Vector (Vector&& that) noexcept
: data_ { std::exchange(that.data_, nullptr) }
, capacity_ { std::exchange(that.capacity_, zero) }
, size_ { std::exchange(that.size_, zero) }
{}
~Vector() {
delete[] data_;
}
Vector& operator=(Vector that) noexcept {
swap(that);
return *this;
}
void reserve(size_type const capacity) {
if (capacity_ < capacity) {
value_type* p{ nullptr };
try { p = new value_type[capacity]; }
catch (std::bad_alloc const&) { throw; }
if (data_ != nullptr)
std::copy(data_, data_ + size_, p);
capacity_ = capacity;
std::swap(data_, p);
delete[] p;
}
}
void swap(Vector& that) noexcept {
using std::swap;
swap(capacity_, that.capacity_);
swap(size_, that.size_);
swap(data_, that.data_);
}
friend void swap(Vector& a, Vector& b) noexcept {
a.swap(b);
}
};
stl
库,我希望它保持原样。(在代码之外使用std::vector
没有矛盾。) - user21508463unique_ptr
(与shared_ptr
不同)很容易自己编写,即使只用于你的MyClass
,它会将所有与内存管理相关的成员函数分离开来。它们一起的代码行数不会比将所有这些放在MyClass
中多太多。 - Sebastianint
要大得多)。 - Fareanor