所以我正在尝试编写一个可以在没有默认构造函数的情况下获取对象的向量类。为此,我使用了一组原始指针。事实上,当我实例化一个新的向量时,让我们称它为2,基于前一个向量,让我们称之为1--它指向前一个对象的底层地址,1。所以当我插入一个新值时1,2也被更新。
#ifndef MYVECTOR_MYVECTOR_H
#define MYVECTOR_MYVECTOR_H
#include <sstream>
#include <stdexcept>
#include <memory>
#include <vector>
#include <ostream>
template<typename T>
class MyVector;
template<typename T>
std::ostream& operator<<(std::ostream& out, const MyVector<T>& myVec){
out << "{";
for(int i = 0; i < myVec.numElem; i++){
out << &myVec.elements[i] << " ";
}
out << "}";
return out;
}
template<typename T>
class MyVector{
public:
int numElem;
int capacity;
T** elements;
MyVector(const unsigned int& numElements, const T& value) : numElem(numElements), capacity(numElements * 2){
elements = new T*[capacity];
for(int i = 0; i < numElem; i++){
elements[i] = new T(value);
}
}
template<typename U>
MyVector(const std::vector<U>& values): numElem(values.size()), capacity(values.size() * 2){
elements = new T*[capacity];
for(int i = 0; i < numElem; i++){
elements[i] = new T(values[i]);
}
}
void insert(const unsigned& pos, const T& value){
elements[numElem] = new T(*elements[numElem - 1]);
numElem++;
for(unsigned int i = numElem - 1; i > pos; i--){
elements[i] = elements[i - 1];
}
elements[pos] = new T(value);
}
};
#endif
根据评论#1:
class NoDefault {
public:
NoDefault(const int& value) : value(value) {}
int value;
};
std::ostream& operator<<(std::ostream& out, const NoDefault& noDefault) {
out << noDefault.value;
return out;
}
int main() {
MyVector<NoDefault> noDefaultVec(std::vector<NoDefault>{7,8,9,10,11});
MyVector<MyVector<NoDefault>> vecvec(2, noDefaultVec);
std::cout << "noDefaultVec = " << noDefaultVec << std::endl;
std::cout << "vecvec = " << vecvec << std::endl;
noDefaultVec.insert(3, 99);
vecvec.insert(1, noDefaultVec);
std::cout << "noDefaultVec = " << noDefaultVec << std::endl;
std::cout << "vecvec = " << vecvec << std::endl;
return 0;
}
答案 0 :(得分:1)
执行浅拷贝而不是深拷贝。
矢量的浅表副本会创建一个与旧元素共享元素的新集合。接下来,对原始对象所做的任何更改都将导致更改新对象。在这种情况下,您需要的是一个深层复制,它复制从源到目标的每个元素。执行这样的复制后,您将获得两个具有单独数据集的向量。
为您的类提供复制构造函数可以解决问题,但您还应该记住基于The Rule Of Three实现析构函数和赋值运算符。您还可以考虑添加移动构造函数和移动赋值运算符(或copy-and-swap idiom之后的一个赋值运算符。)