Home > database >  how to work with deleted object on custom vector
how to work with deleted object on custom vector

Time:07-19

I know that std vectors can work with objects that are not default constructible. However, when I try to implement a slightly modified one myself, I cant seem to make such vector.

class A
{
    public:
       A() = delete;
       A(const int &x)
       :x(x)
       {}
    private:
       int x;
};
template <typename T, int N> //default constructor of the vector
CircularBuffer<T,N>::CircularBuffer()
{
    Size = 0;
    Capacity =N;
    Array = new T[Capacity];
    Start = 0;
    End = 0;
}
template <typename T, int N>
CircularBuffer<T,N>::CircularBuffer(const CircularBuffer& rhs) //copy constructor of the vector
{
    Size = rhs.Size;
    Capacity = rhs.Capacity;
    Array = new T[Capacity];
    Start = rhs.Start;
    End = rhs.End;
    for(int i=0;i<Capacity;i  )
    {
        this->Array[i] = rhs.Array[i];
    }
}
template <typename T, int N> //move constructor of the vector
CircularBuffer<T,N>::CircularBuffer(CircularBuffer&& rhs)
{
    rhs.Swap(*this);
}
template <typename T, int N>
void CircularBuffer<T,N>:: Swap(CircularBuffer &source) 
{
    swap(Size,source.Size);
    swap(Capacity,source.Capacity);
    swap(Start,source.Start);
    swap(End,source.End);
    swap(Array,source.Array);
}

When I try to make a vector with object A,

    CircularBuffer<A,3> v;

error: use of deleted function ‘A::A()’ I get this error which is obviously self explanatory. Anyone can help me solve this??

CodePudding user response:

The problem is here

Array = new T[Capacity];

which default constructs T objects.

std::vector uses placement new to construct objects when they are added to the vector.

Array = (T*)operator new(sizeof(T)*Capacity);

and (when you add the new item)

new(Array   i) T(...); // placement new

where ... are the arguments you wish to pass to the constructor.

See here for more details.

CodePudding user response:

The issue is with the line Array = new T[Capacity];. This needs to default-initialize all members of the array, which it cannot do without a default-constructor.

std::vector gets around it by splitting allocation and construction with its allocator. I recommend you simply use std::allocator as well. Otherwise you can use placement-new to construct the elements after allocating the required memory separately.

  •  Tags:  
  • c
  • Related