VC++Native Wifi API 3---GOTOのリソース解放時の役割

2632 ワード

GOTO文は評判が悪く、私たちの先生は簡単に使わないように教えてくれました.
C++ジャンプ文はgoto,break,continueの3つである.それらはただの道具で、問題は道具のせいにすることはできないと思います.問題は人にあります.
ポインタのようにgotoという無条件ジャンプ文の力は強いが、乱用すれば問題が発生しにくい.
しかし、gotoは確かに2つの選択ではありません.例えば、私が出会ったのは、関数に複数の出口があり、各出口がリソースを解放するとき、解放文を煩わしく書かないよりも、
goto文のようにさっぱりしていないほうがいい.
次の例は、前のNative Wifi APIの記事から取ったもので、私たちのプログラムが常に制御しているwifiのonとoffのため、リソースの解放に注意しなければならない.WlanOpenHandleで言えば、
対称WlanCloseHandlerに注意しないと、プログラムが何回か実行された後にエラーが発生します:ERROR_REMOTE_SESSION_LIMIT_EXCEEDED
公式サイトでは、Too many handles have been issued by the serverと解釈されています.
したがって、各API呼び出し後、戻り値を確認し、エラーが発生した場合、プログラムは下向きに実行されなくなります.returnの前に、リソースを解放する必要があります.出口が多い場合は同じコードをたくさん書きます
イライラして読みにくく、コードが急速に膨張します.しかしgotoを使用すると、問題は簡単になります.簡単な例を見てください.
// ManageWirelessNetwork.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <shellapi.h>
#include <wlanapi.h>

// Need to link with shell32.lib
#pragma comment(lib, "shell32.lib")
#pragma comment(lib, "wlanapi.lib")

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD dwResult = 0;
    DWORD dwMaxClient = 2;
    DWORD dwCurVersion = 0;
    HANDLE hClient = NULL;
    PWLAN_INTERFACE_INFO_LIST pIfList = NULL;
    PWLAN_INTERFACE_INFO pIfInfo = NULL;

    dwResult = WlanOpenHandle(dwMaxClient, NULL, &dwCurVersion, &hClient);
    if (dwResult != ERROR_SUCCESS) {
        wprintf(L"WlanOpenHandle failed with error: %u
", dwResult); return false; } dwResult = WlanEnumInterfaces(hClient, NULL, &pIfList); if (dwResult != ERROR_SUCCESS) { wprintf(L"WlanEnumInterfaces failed with error: %u
", dwResult); goto RELEASE_RESOURCE; } WLAN_PHY_RADIO_STATE state; state.dwPhyIndex = 0; state.dot11SoftwareRadioState = dot11_radio_state_on;//off here too. PVOID pData = &state; dwResult = WlanSetInterface(hClient,&pIfList->InterfaceInfo[0].InterfaceGuid, wlan_intf_opcode_radio_state,sizeof(WLAN_PHY_RADIO_STATE),pData,NULL); if(dwResult == ERROR_SUCCESS) { wprintf(L"set state success!
"); } else { wprintf(L"set state failed!err is %d
",dwResult); } RELEASE_RESOURCE: if(hClient) { WlanCloseHandle(hClient,NULL); hClient = NULL; } if(pIfList) { WlanFreeMemory(pIfList); pIfList = NULL; } if(pIfInfo) { WlanFreeMemory(pIfInfo); pIfInfo = NULL; } return 0; }

最後にgotoは多重ループから飛び出すためにも使われる.しかし、内層から外層にジャンプするしかなく、不可逆的に動作することに注意しなければならない.