通过显式调用 class 构造函数与默认初始化 + 赋值运算符来使用对象

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

考虑以下示例:

#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;
}

因为我只使用 h 来调用 AddHandler() 而不是其他任何东西,所以我想避免完全定义它并在一行中完成所有事情。所以我考虑将其替换为:

wxImage::AddHandler(&wxBMPHandler());

编译正常,但调用 SaveFile() 将不起作用; WxWidgets 将在运行时显示错误 "No image handler for type 1 defined"。

我想在函数调用中创建的对象是临时的,但我不确定。如果不是,我错过了什么,如何避免定义 h?

值得注意的是 AddHandler() 具有以下签名:

static void AddHandler( wxImageHandler *handler );



[更新] 回应 M.M 的评论说:

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

由于在WxWidgets的源代码中找不到operator&的定义,我创建了这个测试项目:

#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;
}

编译正常,运行时没有任何 "hard error" - 唯一需要注意的是屏幕上没有显示任何内容 - (*address).empty() returns 正确。 我什至定义了自己的 class 来测试,而不是 std::string 并产生了相同的行为(没有编译器错误,没有运行时错误,但没有输出)。

我也按照aichao的建议尝试了这种单线,但没有成功:

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

wxImage::AddHandler(&wxBMPHandler());中,临时停止在表达式末尾的生命周期,所以你有悬空指针。

wxBMPHandler h;

wxImage::AddHandler(&h);

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

h 比调用 bm.SaveFile("file.bmp", wxBITMAP_TYPE_BMP); 还长。

您将遇到与

类似的问题
{
    wxBMPHandler h;

    wxImage::AddHandler(&h);
} // End of life time of h

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

我以前从未使用过 wxWidgets,但根据 wxWidgets version 3.1.1 API docs here,您应该使用堆分配的处理程序对象调用 wxImage::AddHandler

wxImage::AddHandler(new wxBMPHandler);

因此,不需要定义h。同样根据文档,此处理程序对象的内存由 wxWidgets 框架管理。具体来说,文档说 handler

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

还有静态成员函数wxImage::CleanUpHandlers()删除所有注册的图像处理器。根据文档:

This function is called by wxWidgets on exit.

因此,您不必自己删除处理程序,除非您特别想要(即释放一些内存)。

希望对您有所帮助。