【发布时间】:2018-05-09 18:19:39
【问题描述】:
实际上我现在有 2 个单独的问题,所以我将这个问题分为 2 个部分。第一个是关于深拷贝和赋值运算符重载
首先,我的班级标题
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];
}
}
在主要
int main() {
MyVector<int> vecA;
//adding elements to vecA
MyVector<int> vecB(vecA);
}
不幸的是我得到的是
g++ -std=gnu++14 -static-libstdc++ -g3 -Icode/include -c 代码/源/my_vector.cpp -o obj/my_vector.o 代码/源/my_vector.cpp:20:1:错误:无效使用模板名称 没有参数列表的“MyVector” MyVector& MyVector::operator=(const MyVector &source) { ^ Makefile:29: 目标“obj/my_vector.o”的配方失败 make: *** [obj/my_vector.o] 错误 1
第 2 部分
在同一个类中,我得到了 extendArray() 函数,如果调用该函数,则将数组容量扩展 2 并将所有元素从旧数组复制到新数组。我尝试使用 for 循环遍历所有元素,它工作得很好,但我想改用 std::swap ,然后我遇到了一些奇怪的麻烦。
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);
}
我只是这样做
int main(){
MyVector<int> test;
test.pushBack(5);
test.pushBack(10);
test.pushBack(15);
test.pushBack(20);
test.pushBack(25);
for(int i = 0; i < test.getCapacity(); i++) {
cout << test[i] << ", ";
}
}
我希望看到以下输出(添加第 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&)
(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) (in /home/maciek/Programming/MyVector/MyVector)
==5967== by 0x403968: operator new[](unsigned long) (in /home/maciek/Programming/MyVector/MyVector)
==5967== by 0x40314B: std::_MakeUniq::__array std::make_unique(unsigned long) (in /home/maciek/Programming/MyVector/MyVector)
==5967== by 0x402F3C: MyVector::MyVector() (my_vector.cpp:6)
==5967== by 0x402C99: main (main.cpp:8)
==5967==
【问题讨论】:
-
关于第 1 部分:您试图在复制构造函数中将 shared_ptr 分配给 unique_ptr。
-
是的,它也应该是复制构造函数中的 make_unique 。不过,和以前一样的错误。没有参数列表的模板名称“MyVector”的使用无效。
-
在赋值运算符实现中,您应该将返回类型指定为 MyVector
而不是 MyVector。 -
是的,我也是这么想的。第 1 部分还好,第 2 部分仍然不知道如何移动。
-
extendArray完全没有意义。这是一个精心设计的无操作:p_array最终持有与它开始时完全相同的指针(嗯,不完全是无操作:p_capacity现在持有一个与实际容量不匹配的值)。我不确定我是否理解你想用它来实现什么,但不管它是什么,这个函数都不会那样做。
标签: c++11 templates swap unique-ptr deep-copy