c++vectorsmart-pointers

std::vector: when is a pointer not a pointer?


I have this existing working code, which I am trying to convert to implementation:

Bitmap *pbitmap = new Bitmap(L"images.png");
nWidth  = pbitmap->GetWidth();
nHeight = pbitmap->GetHeight();
graphics.DrawImage(pbitmap, 950, 200, nWidth, nHeight);

So I now have this almost equivalent code using (Massive thanks to @heap underrun !!)

//  create empty vector container
std::vector<std::unique_ptr<Gdiplus::Bitmap>> my_vec;
//  instantiate one Bitmap object
my_vec.push_back(std::make_unique<Gdiplus::Bitmap>(L"images.png"));
nWidth  = my_vec[0]->GetWidth(); 
nHeight = my_vec[0]->GetHeight();   
Bitmap *pbitmap = (Bitmap *) my_vec[0];
graphics.DrawImage(pbitmap, 950, 200, nWidth, nHeight);

The GetWidth()/GetHeight() lines appear to confirm that my_vec[0] is a Bitmap* ... but the following assignment line fails with the following error:

example1.cpp:143:22: error: invalid cast from type '__gnu_cxx::__alloc_traits<std::allocator<std::unique_ptr<Gdiplus::Bitmap> >, std::unique_ptr<Gdiplus::Bitmap> >::value_type' {aka 'std::unique_ptr<Gdiplus::Bitmap>'} to type 'Gdiplus::Bitmap*'
143 |    Bitmap *pbitmap = (Bitmap *) my_vec[0];

So I still just don't understand how works, and how to utilize it... Advise?


Solution

  • I refer to other answers and comments why your code did not compile.

    What I want to mention is that you do not need the std::vector if you have only one bitmap.

    Create the bitmap directly on the stack

    Gdiplus::Bitmap bitmap(L"images.png");
    nWidth  = bitmap.GetWidth();
    nHeight = bitmap.GetHeight();
    graphics.DrawImage(&bitmap, 950, 200, nWidth, nHeight);
    

    Create the bitmap on the heap

    auto bitmap = std::make_unique<Gdiplus::Bitmap>(L"images.png");
    nWidth  = bitmap->GetWidth();
    nHeight = bitmap->GetHeight();
    graphics.DrawImage(bitmap.get(), 950, 200, nWidth, nHeight);
    

    bitmap is an object (and not a pointer) of type std::unique_ptr<Gdiplus::Bitmap>. During destruction, the Gdiplus::Bitmap object it points to will also be destroyed. There is no need to put the unique_ptr into a container.