C++ 结构在函数 returns 之后析构
C++ struct is destruct after the function returns
我在另一个函数中翻译的位图结构在函数 returns
之后设置为 NULL
函数:
HRESULT RessourcesLoader::decode(LPCWSTR name,ID2D1Bitmap* bitmap1) {
int hr = S_OK;
hr = LoadFile(name, bitmap1);
assert(SUCCEEDED(hr));
hr = rendertarget->CreateBitmapFromWicBitmap(wicConverter, NULL, &bitmap1);
assert(SUCCEEDED(hr));
return hr;
在这里打电话:
ID2D1Bitmap* bmp1=NULL;
ID2D1Bitmap* bmp2=NULL;
rl->decode(L"Menu_corner.png", bmp1);
rl->decode(L"Menu_side.png", bmp2);
(在函数 hr 内部是 S_OK 并且结构中包含所有内容,一旦函数 return 指针为 NULL)
是范围问题吗?
请记住,像 ID2D1Bitmap* bitmap1
这样的 C++ 参数是 passed by value。这意味着您有两个完全独立(并且几乎不相关)的变量 bmp1
和 bitmap1
。这两个变量唯一的关系是 bitmap1
以与调用 decode
时 bmp1
相同的值开始生命 - 即 NULL
.
你的decode
逻辑调用CreateBitmapFromWicBitmap
传入bitmap1
的地址,CreateBitmapFromWicBitmap
小心地用新创建的位图的地址填充bitmap1
。 但是 根本不会影响 bmp1
。所以 bmp1
仍然设置为空。您可以通过在 return hr
上放置断点然后查看 bmp1
和 bitmap1
.
的内容来自行检查
如果您希望解码更改 bmp1
的内容,您需要将 bmp1
的地址而不是内容传递给 decode
。这意味着 bitmap1 应该是 ID2D1Bitmap **
类型并且 decode 应该这样调用... rl->decode(L"Menu_corner.png", &bmp1);
更新
一些评论指出我说 "C++ parameters are passed by value" 时相当粗心,我已将上面的文字改写为更加集中。
评论还指出,C++ 参数既可以按引用传递,也可以按值传递。在 decode
函数的情况下,使用语法 ID2D1Bitmap*& bitmap1
.
我不得不承认我对 ID2D1Bitmap** bitmap1
和 ID2D1Bitmap*& bitmap1
的相对优点有些矛盾。但这可能更多地说明了我的个人偏见。
您正在将位图指针的 副本 传递给您的函数。您的函数修改了副本,但这对创建副本的原始指针没有影响。
如果您想修改传递给函数的指针,您需要传递一个引用或指向它们的指针:
HRESULT RessourcesLoader::decode(LPCWSTR name, ID2D1Bitmap*& bitmap1) {
// ^----- Pass by reference
int hr = S_OK;
hr = LoadFile(name, bitmap1);
assert(SUCCEEDED(hr));
hr = rendertarget->CreateBitmapFromWicBitmap(wicConverter, NULL, &bitmap1);
assert(SUCCEEDED(hr));
return hr;
}
我在另一个函数中翻译的位图结构在函数 returns
之后设置为 NULL函数:
HRESULT RessourcesLoader::decode(LPCWSTR name,ID2D1Bitmap* bitmap1) {
int hr = S_OK;
hr = LoadFile(name, bitmap1);
assert(SUCCEEDED(hr));
hr = rendertarget->CreateBitmapFromWicBitmap(wicConverter, NULL, &bitmap1);
assert(SUCCEEDED(hr));
return hr;
在这里打电话:
ID2D1Bitmap* bmp1=NULL;
ID2D1Bitmap* bmp2=NULL;
rl->decode(L"Menu_corner.png", bmp1);
rl->decode(L"Menu_side.png", bmp2);
(在函数 hr 内部是 S_OK 并且结构中包含所有内容,一旦函数 return 指针为 NULL) 是范围问题吗?
请记住,像 ID2D1Bitmap* bitmap1
这样的 C++ 参数是 passed by value。这意味着您有两个完全独立(并且几乎不相关)的变量 bmp1
和 bitmap1
。这两个变量唯一的关系是 bitmap1
以与调用 decode
时 bmp1
相同的值开始生命 - 即 NULL
.
你的decode
逻辑调用CreateBitmapFromWicBitmap
传入bitmap1
的地址,CreateBitmapFromWicBitmap
小心地用新创建的位图的地址填充bitmap1
。 但是 根本不会影响 bmp1
。所以 bmp1
仍然设置为空。您可以通过在 return hr
上放置断点然后查看 bmp1
和 bitmap1
.
如果您希望解码更改 bmp1
的内容,您需要将 bmp1
的地址而不是内容传递给 decode
。这意味着 bitmap1 应该是 ID2D1Bitmap **
类型并且 decode 应该这样调用... rl->decode(L"Menu_corner.png", &bmp1);
更新
一些评论指出我说 "C++ parameters are passed by value" 时相当粗心,我已将上面的文字改写为更加集中。
评论还指出,C++ 参数既可以按引用传递,也可以按值传递。在 decode
函数的情况下,使用语法 ID2D1Bitmap*& bitmap1
.
我不得不承认我对 ID2D1Bitmap** bitmap1
和 ID2D1Bitmap*& bitmap1
的相对优点有些矛盾。但这可能更多地说明了我的个人偏见。
您正在将位图指针的 副本 传递给您的函数。您的函数修改了副本,但这对创建副本的原始指针没有影响。
如果您想修改传递给函数的指针,您需要传递一个引用或指向它们的指针:
HRESULT RessourcesLoader::decode(LPCWSTR name, ID2D1Bitmap*& bitmap1) {
// ^----- Pass by reference
int hr = S_OK;
hr = LoadFile(name, bitmap1);
assert(SUCCEEDED(hr));
hr = rendertarget->CreateBitmapFromWicBitmap(wicConverter, NULL, &bitmap1);
assert(SUCCEEDED(hr));
return hr;
}