xd96dx Docs
  • c/c++
    • 网络编程
      • linux 网络
        • linux 网络io模型
        • Signal-Driven I/O Model(信号驱动)
        • Asynchronous I/O Model(异步IO)
      • IO多路复用
        • select 示例
        • poll 示例
        • epoll 示例
      • Reactor实例之 muduo 源码分析
    • stl实现
      • 容器(Containers)
        • Vector(动态数组)
        • List(双向链表)
        • Deque(二级动态数组)
  • 游戏开发
    • skynet 从demo到源码
      • server-client demo
      • skynet 源码分析-启动流程之初始化
      • skynet 源码分析-启动流程之创建service
      • skynet 源码分析-启动流程之线程池启动
Powered by GitBook
On this page
  1. c/c++
  2. stl实现
  3. 容器(Containers)

Vector(动态数组)

#pragma once

namespace XD
{
	template <typename T>
	class Vector
	{
	private:
		void expand()
		{
			capacity_ = capacity_ == 0 ? 1 : capacity_ * 2;
			T* new_data_ = new T[capacity_];
			for (auto i = 0; i < size_; i++) {
				new_data_[i] = std::move(data_[i]);
			}
			delete[] data_;
			data_ = new_data_;
		}

	public:
		using value_type = T;

		// 默认构造
		Vector() : data_(nullptr), capacity_(0), size_(0)
		{ }


		Vector(size_t n)
		{
			size_ = n;
			capacity_ = n;
			data_ = new T[n];
			//data_ = static_cast<T*>(operator new(capacity_) );
		}

		explicit Vector(size_t n, const T& val)
		{
			size_ = n;
			capacity_ = n;
			data_ = new T[n];
			if (data_) {
				for (size_t i = 0; i < n; i++) {
					data_[i] = val;
				}
			}
		}

		// 拷贝构造
		Vector(const Vector<T>& other)
		{
			size_ = other.size_;
			capacity_ = size_;
			data_ = new T[size_];
			memcpy(data_, other.data_, capacity_);  // 只支持基础类型, 如果存放的为对象, 在此处有可能有bug
		}

		// 赋值构造
		Vector operator=(const Vector<T>& other)
		{
			if (this != other) {
				delete[] data_;
				size_ = other.size_;
				capacity_ = size_;
				data_ = new T[size_];
				memcpy(data_, other.data_, capacity_); // 只支持基础类型, 如果存放的为对象, 在此处有可能有bug
			}
			return *this;
		}

		// 移动构造
		Vector(Vector&& other)
		{
			data_ = other.data_;
			capacity_ = other.capacity_;
			size_ = other.size_;

			other.data_ = nullptr;
			other.capacity_ = 0;
			other.size_ = 0;
		}

		// 析构函数
		~Vector() 
		{
			delete[] data_;
			capacity_ = 0;
			size_ = 0;
		}

		// 测试函数
		void print_() {
			std::cout << "cap: " << capacity_ << std::endl;
			std::cout << "size: " << size_ << std::endl;
			for (int i = 0; i < size_; i++) {
				std::cout << data_[i] << std::endl;
			}
		}

		size_t get_size()
		{
			return size_;
		}

		size_t get_capacity()
		{
			return capacity_;
		}

		T* data()
		{
			return data_;
		}

		bool empty()
		{
			return size_ == 0;
		}

		void push_back(T&& value) 
		{
			if (size_ == capacity_) {
				expand();
			}

			data_[size_++] = value;
		}

		T& operator[](size_t index) {
			return this->at(index);
		}

		// 获取第一个元素
		T& front() {
			return data_[0];
		}

		// 获取最后一个元素
		T& back() {
			return data_[size_ - 1];
		}

		T& at(size_t index) {
			if (index >= size_) {
				throw std::out_of_range("Index out of range");
			}
			return data_[index];
		}


	private:
		T* data_;
		size_t capacity_;
		size_t size_;
	};
}

注意的点:

  • 赋值构造时, 要判断other 是不是this

  • 拷贝数据时, 只有基础类型才能使用 memcpy 或者 std::copy, 如果是对象, 则需要循环拷贝

Previous容器(Containers)NextList(双向链表)

Last updated 4 months ago