深层复制和赋值重载以及std :: swap

时间:2017-11-26 10:39:11

标签: c++11 templates swap unique-ptr deep-copy

实际上我现在有两个不同的问题,所以我将这个问题分为两部分。第一个是深度复制和分配运算符重载

首先,我的班级标题

ChildClass

这是我的复制构造函数和赋值运算符重载函数

template <class T>
class MyVector{    
    std::unique_ptr<T[]> p_array;
    int p_size; 
    int p_capacity; 
public: 
    MyVector();
    MyVector(const MyVector&);
    MyVector& operator= (const MyVector&);
}

主要

template <class T>
MyVector<T>::MyVector(const MyVector &source) {
    p_capacity = source.p_capacity;
    p_size = source.p_size;
    p_array = std::make_shared<T[]>(p_capacity);
    for(int i = 0; i < p_capacity; i++) {
        p_array[i] = source.p_array[i];
    }
}

template <class T>
MyVector& MyVector<T>::operator=(const MyVector &source) {
    if(this == &source) return *this;

    p_capacity = source.m_capacity;
    p_size = source.m_size;

    p_array = std::make_unique<T[]>(p_capacity);
    for(int i = 0; i < p_capacity; i++) {
        p_array[i] = source.p_array[i];
    }
}

不幸的是我得到的是

  

g ++ -std = gnu ++ 14 -static-libstdc ++ -g3 -Icode / include -c   code / source / my_vector.cpp -o obj / my_vector.o   code / source / my_vector.cpp:20:1:错误:无效使用template-name   'MyVector'没有参数列表MyVector&amp;   MyVector :: operator =(const MyVector&amp; source){^ Makefile:29:   目标'obj / my_vector.o'的配方失败了make:*** [obj / my_vector.o]   错误1

第2部分

在同一个类中,我得到了extendArray()函数,如果调用它,则将数组容量扩展2并将旧数组中的所有元素复制到new。我尝试使用for循环迭代所有元素,它工作得很好,但我想使用std :: swap代替然后我遇到了一些奇怪的麻烦。

int main() {
MyVector<int> vecA;
//adding elements to vecA
MyVector<int> vecB(vecA);
}

主要是我这样做

template <class T>
void MyVector<T>::extendArray() {
    p_capacity *= 2;
    std::unique_ptr<T[]> temp_array = std::make_unique<T[]>(p_capacity/2);
    std::swap(p_array, temp_array);
    p_array.reset();
    p_array = std::make_unique<T[]>(p_capacity);
    std::swap(temp_array, p_array);
}

我希望看到以下输出(一旦添加第4个元素,调用extendArray()函数,它将容量从4扩展到8) 5,10,15,20,25,0,0,0 当我使用基于for循环的旧的extendArray()函数时,我得到了它,但是如果我使用std :: swap的那个我得到了 5,10,15,20,25,0,1041,0 我不知道1041来自哪里。更重要的是,valgrind在4个上下文中显示9个错误:

  

== 5967 ==写入大小4无效   == 5967 ==在0x403000:MyVector :: pushBack(int const&amp;)
(my_vector.cpp:17)
  == 5967 == by 0x402CE7:main(main.cpp:11)
  == 5967 ==地址0x542bc88是大小为8的块后的0字节   == 5967 ==在0x4C2DB8F:malloc(在/usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  == 5967 == by 0x404707:operator new(unsigned long)(在/ home / maciek / Programming / MyVector / MyVector中)
  == 5967 == by 0x403968:operator new [](unsigned long)(在/ home / maciek / Programming / MyVector / MyVector中)
  == 5967 == by 0x40314B:std :: _ MakeUniq :: __ array std :: make_unique(unsigned long)(in   /家庭/ maciek /编程/ MyVector / MyVector)
  == 5967 == by 0x402F3C:MyVector :: MyVector()(my_vector.cpp:6)
  == 5967 == by 0x402C99:main(main.cpp:8)
  == 5967 ==

1 个答案:

答案 0 :(得分:0)

要点是将所有元素from_array复制到临时数组中,为m_array分配新的,更大的大小(容量),然后将临时数组中的元素复制回m_array。我用以下代码找到了解决方案:

template <class T>
void MyVector<T>::extendArray() {
    m_capacity *= 2;
    std::unique_ptr<T[]> temp_array = std::move(m_array);
    m_array = std::make_unique<T[]>(m_capacity);
    std::copy(temp_array.get(), temp_array.get() + m_capacity/2, m_array.get());        
}

工作得很好。 pushBack()方法在上面的代码中没有显示,因为它与我的问题无关,它只检查是否有足够的空间用于新元素(如果没有,则调用extendArray())并在此处添加此元素阵列结束。