首页 > 解决方案 > 使用 unique_ptr 跟进的通用向量类

问题描述

我正在尝试使用 std::unique_ptr 实现一个通用向量类。这是我第一次使用智能指针这样做,所以我知道我可能会犯愚蠢的错误。我只是不明白这些错误:

1>------ Build started: Project: Vector, Configuration: Debug Win32 ------
1>main.cpp
1>c:\dev\vector\vector\vector.h(109): error C2676: binary '[': 'std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(105): note: while compiling class template member function 'Vector<int>::Vector(int,const T &)'
1>        with
1>        [
1>            T=int
1>        ]
1>c:\dev\vector\vector\main.cpp(19): note: see reference to function template instantiation 'Vector<int>::Vector(int,const T &)' being compiled
1>        with
1>        [
1>            T=int
1>        ]
1>c:\dev\vector\vector\main.cpp(14): note: see reference to class template instantiation 'Vector<int>' being compiled
1>c:\dev\vector\vector\vector.h(172): error C2676: binary '[': 'const std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(170): note: while compiling class template member function 'void Vector<int>::display(std::ostream &) const'
1>c:\dev\vector\vector\vector.h(80): note: see reference to function template instantiation 'void Vector<int>::display(std::ostream &) const' being compiled
1>c:\dev\vector\vector\vector.h(182): error C2676: binary '[': 'const std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(178): note: while compiling class template member function 'int Vector<int>::get(int) const'
1>c:\dev\vector\vector\main.cpp(23): note: see reference to function template instantiation 'int Vector<int>::get(int) const' being compiled
1>c:\dev\vector\vector\vector.h(190): error C2676: binary '[': 'std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(186): note: while compiling class template member function 'void Vector<int>::set(int,const T &)'
1>        with
1>        [
1>            T=int
1>        ]
1>c:\dev\vector\vector\main.cpp(22): note: see reference to function template instantiation 'void Vector<int>::set(int,const T &)' being compiled
1>        with
1>        [
1>            T=int
1>        ]
1>c:\dev\vector\vector\vector.h(225): error C2676: binary '[': 'std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(215): note: while compiling class template member function 'void Vector<int>::insert(int,T &&)'
1>        with
1>        [
1>            T=int
1>        ]
1>c:\dev\vector\vector\main.cpp(30): note: see reference to function template instantiation 'void Vector<int>::insert(int,T &&)' being compiled
1>        with
1>        [
1>            T=int
1>        ]
1>c:\dev\vector\vector\vector.h(225): error C2088: '[': illegal for class
1>c:\dev\vector\vector\vector.h(227): error C2676: binary '[': 'std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(238): error C2676: binary '[': 'std::unique_ptr<T,std::default_delete<_Ty>>' does not define this operator or a conversion to a type acceptable to the predefined operator
1>        with
1>        [
1>            T=int,
1>            _Ty=int
1>        ]
1>c:\dev\vector\vector\vector.h(232): note: while compiling class template member function 'void Vector<int>::remove(int)'
1>c:\dev\vector\vector\main.cpp(28): note: see reference to function template instantiation 'void Vector<int>::remove(int)' being compiled
1>c:\dev\vector\vector\vector.h(238): error C2088: '[': illegal for class
1>Done building project "Vector.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

从我收集的信息来看,我不能将“[]”与唯一的ptr一起使用?我应该不使用唯一的 ptr 并使用共享的 ptr 吗?

这是头文件:

#ifndef Vector_h
#define Vector_h



template <class T>
class Vector {
private:

    static constexpr int initial_capacity = 100;

    // Instance variables
    int capacity = 0;
    int size = 0;
    std::unique_ptr<T> data = nullptr;

    void deepCopy(const Vector<T> &source) {
        capacity = source.size + initial_capacity;
        for (int i = 0; i < source.size; i++) {
            data[i] = source.data[i];
        }
        size = source.size;
    }

    void expandCapacity() {
        auto oldData = std::move(data);
        capacity *= 2;
        for (int i = 0; i < size; i++) {
            data[i] = oldData[i];
        }
    }

public:

    // Constructors
    Vector() = default;                                 // empty constructor
    Vector(int n, const T &value);                      // constructor
    Vector(Vector<T> const &vec);                       // copy constructor
    Vector<T>& operator=(Vector<T> const &rhs);         // assignment operator

    // Rule of 5
    Vector(Vector<T> &&move) noexcept;                  // move constructor
    Vector& operator=(Vector<T> &&move) noexcept;       // move assignment operator
    ~Vector();                                          // destructor

    // Overload operators
    T& operator[](int index);
    T const& operator[](int index) const;
    bool operator==(const Vector<T>&) const;

    //Vector<T>& operator+=(const Vector<T> &other) {
    //  Vector<T> newValue(size + other.size);

    //  std::copy(this->data, this->data + this->size, newValue.data);
    //  std::copy(other.data, other.data + other.size, newValue.data + this->size);

    //  newValue.swap(*this);
    //}

    friend Vector<T>& operator+(Vector<T> &source1, Vector<T> &source2) {
        int n = source1.getSize() + source2.getSize();
        static Vector<T> newSource(n,0);
        for (int i = 0; i < source1.size; i++) {
            newSource[i] = source1[i];
        }

        for (int i = 0; i < source2.size; i++) {
            newSource[i + source1.getSize()] = source2[i];
        }

        return newSource;
    }

    friend std::ostream& operator<<(std::ostream &str, Vector<T> &data) {
        data.display(str);
        return str;
    }

    // Member functions
    void swap(Vector<T> &other) noexcept;
    void display(std::ostream &str) const;
    int getSize() const { return size; }
    int getCapacity() const { return capacity; }
    bool empty() const { return size == 0; }
    void clear() { size = 0; }
    T get(int index) const;
    void set(int index, const T &value);
    void set(int index, T &&value);
    void insert(int index, const T &value); 
    void insert(int index, T &&value);
    void remove(int index);
    void push_back(const T &value);
    void pop_back();

};



template <class T>
Vector<T>::Vector(int n, const T &value) {
    capacity = (n > initial_capacity) ? n : initial_capacity;
    size = n;
    for (int i = 0; i < n; i++) {
        data[i] = value;
    }
}

template <class T>
Vector<T>::Vector(Vector<T> const &vec) {
    deepCopy(vec);
}

template <class T>
Vector<T>::Vector(Vector<T> &&move) noexcept {
    move.swap(*this);
}



#endif /* Vector_h */

这是 main.cpp 文件:

#include <algorithm>
#include <initializer_list>
#include <iostream>
#include <cassert>
#include <ostream>
#include "Vector.h"


int main() {

    ///////////////////////////////////////////////////////////////////////
    ///////////////////////////// VECTOR //////////////////////////////////
    ///////////////////////////////////////////////////////////////////////
    Vector<int> nullVector;                        // Declare an empty Vector
    assert(nullVector.getSize() == 0);                 // Make sure its size is 0
    assert(nullVector.empty());                    // Make sure the vector is empty
    assert(nullVector.getCapacity() == 100);          // Make sure its capacity is greater than 0

    Vector<int> source(20, 0);                      // Declare a 20-element zero Vector
    assert(source.getSize() == 20);                 // Make sure its size is 20
    for (int i = 0; i < source.getSize(); i++) {
        source.set(i, i);
        assert(source.get(i) == i);                 // Make sure the i-th element has value i
    }






    return 0;
}

标签: c++vector

解决方案


当您假设时,您正确理解了错误消息

从我收集到的信息中,我不能使用[]独特的 ptr?

准确地说,您不应该使用[]with unique_ptr<T>whenT不是数组类型。不过,您可以使用operator[]on unique_ptr<T[]>。关键unique_ptr是当unique_ptr拥有一个对象被破坏时隐含的所有权跟踪和自动删除。它与operator delete. 此运算符不得与使用分配的数组一起使用new T[count],而只能与使用 分配的单个对象一起使用new T(constructor parameters)。另一方面, 的一个特殊情况unique_ptr,拼写为unique_ptr<T[]>,用delete[]在它的对象上。因此,unsingunique_ptr<T[]>而不是unique_ptr<T>解决了没有[]以及 unsing 错误的删除功能的问题。


推荐阅读