You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现自定义Wector类的swap函数?附std::vector swap实现疑问

问题

我想实现一个类似std::vector的自定义Wector类,让它拥有移动构造和移动赋值运算符来避免拷贝操作,类声明如下:

class Wector{

public:
    ~Wector();
    Wector();
    Wector(std::size_t s);
    Wector(std::size_t s, const double nr);
    Wector(const std::initializer_list<double> il);

    //copy constructor
    Wector(const Wector & w);
    //move constructor
    Wector(Wector&& w);

    std::size_t size() const;

    double* begin(); // iterator begin
    double* end(); // iterator end
    const double* begin() const; // const iterator begin
    const double* end() const; // const iterator

    const double& operator[](std::size_t i)const;
    double& operator[](std::size_t i);

    Wector& operator=(const Wector& w);
    
    //move assignment
    Wector& operator=(Wector&& w);

private: 
    std::size_t wsize;
    void swap(Wector& w);
    double *element; // double *element = new double[s]
};

我已经写出了移动构造和移动赋值的代码:

//move constructor
Wector::Wector(Wector&& w)
    : Wector() 
{
    swap(w);
}


//move assignment
Wector& Wector::operator=(Wector&& w){
    swap(w);
    return *this;
}

但我不知道怎么在不直接拷贝元素、不借助迭代器拷贝的情况下实现swap函数,我当前尝试的代码是这样的:

void Wector::swap(Wector& v){
    std::swap(wsize, v.size());
    double * temp = new double[v.size()];
    std::copy(w.begin(), w.end(), temp);
    std::swap(element, temp);
    delete [] temp; //edited
}

想请教一下:std::vector中的swap函数是怎么实现的?


解答

std::vector的swap实现逻辑

std::vector的swap是常量时间的高效操作,完全不会拷贝任何元素。它本质上就是交换两个vector对象内部的核心成员:

  • 指向底层数组的指针
  • 记录当前元素数量的size值
  • 记录容器总容量的capacity值(你的Wector没设计这个成员,但核心逻辑一致)

整个过程只交换几个指针和数值,不需要分配新内存,也不需要销毁或拷贝元素,效率拉满。

你的Wector正确的swap实现

你的Wector只需要交换wsize和element这两个私有成员就行,完全不用碰元素拷贝。因为swap是类的成员函数,有权访问同类对象的私有成员,修改后的代码如下:

void Wector::swap(Wector& v){
    // 交换两个对象的元素数量
    std::swap(this->wsize, v.wsize);
    // 交换两个对象的底层数组指针
    std::swap(this->element, v.element);
}

你之前的实现问题在哪

你之前的代码做了完全没必要的内存分配和元素拷贝,彻底违背了swap(以及移动语义)的初衷——避免拷贝。而且std::swap(wsize, v.size())这行是错误的:size()返回的是临时值,不能作为std::swap的左操作数。

补充说明

这个swap正好能完美配合你已有的移动构造和移动赋值:

  • 移动构造时,先默认构造一个空的Wector,再和传入的右值对象交换成员,原右值对象会变成空状态,销毁时不会影响新对象的内存
  • 移动赋值时,直接交换当前对象和右值对象的成员,原对象的内存会被右值对象的析构函数处理,全程无拷贝

内容的提问来源于stack exchange,提问作者Suslik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 09:40:27