首先,我正在尝试创建自己的Vector类(基于STL Vector),只是为了练习一些C ++。不幸的是,当我开始使用shared_ptr时遇到了一些问题。
template <class T>
class MyVector{
std::shared_ptr<T> p_array;
int p_size;
int p_capacity;
public:
MyVector();
void pushBack(T);
T getBegin();
};
构造
template <class T>
MyVector<T>::MyVector() : p_capacity(2), p_size(0) {
std::shared_ptr<T> p_array(new T[p_capacity], std::default_delete<T[]>() );
}
pushBack方法
template <class T>
void MyVector<T>::pushBack(T m_element) {
p_array.get()[p_size] = m_element;
p_size++;
}
getBegin方法
template <class T>
T MyVector<T>::getBegin() {
return p_array.get()[0];
}
然后在主
int main(){
MyVector<int> test;
test.pushBack(4);
cout << "Begin of vector: " << test.getBegin();
}
用g ++编译后得到的是Segmentation fault(core dumped) 我想得到的只是添加到矢量的第一个元素的值。如果它在原始指针上完成,一切正常。
答案 0 :(得分:1)
您遇到的问题存在一些问题。
第一个是你的构造函数创建一个与成员同名的 local 变量,这意味着它不会分配给成员。将构造函数更改为:
template <class T>
MyVector<T>::MyVector() : p_capacity(2), p_size(0) {
p_array(new T[p_capacity], std::default_delete<T[]>() );
}
然而,会导致编译错误,因为在调用类构造函数的主体之前已经构造了成员变量(在这种情况下使用默认构造函数),并且您无法再次构造它。因此,最简单的方法是编译这些代码并且#34;工作&#34;是使用作业:
template <class T>
MyVector<T>::MyVector() : p_capacity(2), p_size(0) {
p_array = std::shared_ptr<T>(new T[p_capacity], std::default_delete<T[]>() );
}
但请注意,这有点误导,因为shared_ptr<T>
通常表示它包含指向单个元素的指针。从C ++ 17开始,已经调整了数组智能指针的规则,以便您也可以使用shared_ptr<T[]>
。
但是:正如Richard Critten所指出的,unique_ptr
在这种情况下可能更合适,因为你的MyVector
类是数组的唯一所有者。
事实上,std::unique_ptr
支持T[]
作为模板参数,可以简化代码:
首先,您可以将您的班级声明更改为:
class MyVector{
std::unique_ptr<T[]> p_array; //clearer that it is holding an array
// rest remains unchanged
并且您的构造函数可以(使用C ++ 14 std::make_unique
)变为:
template <class T>
MyVector<T>::MyVector() : p_capacity(2), p_size(0) {
p_array = std::make_unique<T[]>(p_capacity);
}
std::unique_ptr
对operator[]
也有重载,这意味着你也可以移除.get()
(pushBack
和getBegin
),例如:< / p>
template <class T>
T MyVector<T>::getBegin() {
// should check first that p_size is bigger 0!
return p_array[0];
}