Search code examples
c++functionpointerswxwidgets

Using an object by calling class constructor explicitly vs by default initialization + assignment operator


Considering the following example:

#include <wx/bitmap.h>

int main()
{
    wxBMPHandler h;

    wxImage::AddHandler(&h);

    wxBitmap bm = wxBitmap(200, 200);
    bm.SaveFile("file.bmp", wxBITMAP_TYPE_BMP);

    return 0;
}

Since I'm only using h to call AddHandler() and not for anything else, I'd like to avoid defining it altogether and do the whole thing in one line. So I thought about replacing that with:

wxImage::AddHandler(&wxBMPHandler());

which compiles fine, but calling SaveFile() won't work then; WxWidgets will present an error stating "No image handler for type 1 defined" at runtime.

I guess the object created inside the function call is temporary, but I'm not sure about that. If not, what am I missing, and how can I avoid defining h?

It's worth noting that AddHandler() has the following signature:

static void AddHandler( wxImageHandler *handler );



[Update] In response to M.M's comment saying:

wxImage::AddHandler(&wxBMPHandler()); should fail to compile, unless that class has overloaded operator& for rvalues

Since I couldn't find a definition for operator& in WxWidgets' source code, I created this test project:

#include <iostream>
#include <string>

using namespace std;

string* address = nullptr;

void testing(string* input)
{
    *input = "Something else entirely";
    address = input;
}

int main()
{
    testing(&string("Life is a test"));

    cout << *address << endl;

    cin.get();
    return 0;
}

It compiles fine, and runs without any "hard error" - the only caveat is that nothing is shown in the screen - (*address).empty() returns true. I even defined my own class to test with, instead of std::string and yielded the same behavior (no compiler error, no runtime error, but no output).

I also tried this one-liner, as suggested by aichao, without success:

wxImage::AddHandler(shared_ptr<wxBMPHandler>(new wxBMPHandler()).get());

Solution

  • I've never used wxWidgets before, but according to the wxWidgets version 3.1.1 API docs here, you should call wxImage::AddHandler using a heap-allocated handler object:

    wxImage::AddHandler(new wxBMPHandler);
    

    Therefore, there is no need for defining h. Also according to the docs, the memory for this handler object is managed by the wxWidgets framework. Specifically, the docs says that the handler is a

    heap-allocated handler object which will be deleted by wxImage if it is removed later by RemoveHandler() or at program shutdown.

    There is also the static member function wxImage::CleanUpHandlers() to delete all registered image handlers. According to the docs:

    This function is called by wxWidgets on exit.

    Therefore, you do not have to delete the handler yourself unless you specifically want to (i.e., to free up some memory).

    Hope this helps.