Destructor is called when I push_back to the vector

前端 未结 4 566
青春惊慌失措
青春惊慌失措 2020-12-19 18:38

I have this class definition:

class FlashStream
{
public:
    explicit FlashStream(const char * url, vector * headers, vector * dat         


        
4条回答
  •  自闭症患者
    2020-12-19 18:47

    Destructor at push_back could be called in two cases.

    First case, as was noted, occurs when you push temporary object to vector. This is not the best idea, since constructor, copy constructor and destructor will be called. You may store pointers to object in your vector to avoid redundant calls.

    C++ 11 comes with new features that might help you.

    To avoid unnecessary copying use std::vector::emplace_back(Args&&... args)

    It constructs object in-place in vector instead of copying.

    Also you may use move version of push_back(value_type&& val). Just define move constructor in your class, and move version of push_back will work automatically for temporary objects.

    The second case when destructor is called is reaching capacity of the vector. Vector has two major values: size and capacity. Size is a number of elements currently held in vector. Capacity is size of internal vector storage measured in units of element type. So, when you push back element you are increasing size of vector. If size of storage is not enough to push new element, vector performs reallocation to increase its capacity. After reallocation vector re-constructs its object using copy constructor and deletes old objects using destructor. So, at psuh_back vector could invoke destructor of the object multiple times.

    To decrease cost of vector re-size at puhs_back, always use std::vector::reserve method to preallocate storage for your objects.

    std::vector vec;
    vec.reserve(20);
    for(int i = 0; i<20; ++i)
        vec.push_back(i)
    

    Also you may decrease cost of object copying by defining move constructor.

    class C
    {
    public:
        C(int c)
            : m_c(c)
        {
            std::cout << "C(int c)" << std::endl;
        }
        C(C&& c)
            : m_c(c.m_c)
        {
            std::cout << "C(C&& c)" << std::endl;
        }
        C(const C& c)
            : m_c(c.m_c)
        {
            std::cout << "C(const C& c)" << std::endl;
        }
        ~C()
        {
            std::cout << "~C()" << std::endl;
        }
    private:
        int m_c;
    };
    
    int main()
    {
        std::vector vc;
        for (int i = 0; i < 100; ++i)
            vc.push_back(C(i));
        return 0;
    }
    

    If you compile and run it you will see that "C(const C& c)" was not called at all. Since move version of constructor is defined, push_back and reallocate will move your object instead of copying.

提交回复
热议问题