首页 > 解决方案 > 在实时项目中哪些场景可以使用虚函数?

问题描述

我对虚拟功能概念有很好的了解。并且可以创建一个虚函数示例程序,并且可以详细讲解。

但是当我看到实时项目时,我对它的实施方式感到困惑。

下面是虚函数的实现。我对下面的实现感到困惑,因为我可能在这里遗漏了一些东西。

谁能解释一下下面的实现?

在基类 CHeadsetControl "IsDevicePresent" 中实现纯虚函数,如下所示:

耳机控制.h

class HEADSETCONTROL_API CHeadsetControl{
virtual BOOL    IsDevicePresent (VOID) = 0;
};

我们从 CHeadsetControl 类派生一个类 CHeadsetControlUSB,如下所示:

耳机控制USB.h

 class CHeadsetControlUSB : public CHeadsetControl 
    {
    virtual BOOL    IsDevicePresent (VOID);
    };

来自 CHeadsetControlUSB 类的 IsDevicePresent() 实现如下所示:

耳机控制USB.cpp

  BOOL CHeadsetControlUSB::IsDevicePresent()
    {
        return theHeadsetDevice.IsDevicePresent();
    }

这里“theHeadsetDevice”是类“CHeadsetDevice”的对象。而 CHeadsetDevice 类如下图所示:

CHeadsetDevice 类实现如下图所示:

耳机设备.h

这里如果我们看到下面的 CHeadsetDevice 类,它不是从 CHeadsetControlUSB 类派生的。但它使用的是 CHeadsetControlUSB 类。

如果我们使用如下所示的 CHeadsetControlUSB 类,那么这意味着什么?

class CHeadsetControlUSB;

class HEADSETDEVICE_API CHeadsetDevice 
{

BOOL      IsDevicePresent() const;

};

IsDevicePresent() 在 HeadsetDevice.cpp 中实现,如下所示:

 BOOL CHeadsetDevice::IsDevicePresent() const
    {
        BOOL result = FALSE;
        HDEVINFO DeviceInfoSet;
    GUID hidGuid;
    HidD_GetHidGuid(&hidGuid);
    
        DeviceInfoSet = SetupDiGetClassDevs(&hidGuid,0,0,DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
    
        if (DeviceInfoSet != INVALID_HANDLE_VALUE)
        {
            SP_DEVICE_INTERFACE_DATA DeviceInfoData;
    
            DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    
            for (DWORD index=0; SetupDiEnumDeviceInterfaces(DeviceInfoSet,
                                                            0,
                                                            &hidGuid,
                                                            index,
                                                            &DeviceInfoData); index++)
            {
                DWORD requiredSize = 0;
    
                SetupDiGetDeviceInterfaceDetail(DeviceInfoSet,
                                                &DeviceInfoData,
                                                0,
                                                0,
                                                &requiredSize,
                                                0);
    
                PSP_INTERFACE_DEVICE_DETAIL_DATA detail =
                    (PSP_INTERFACE_DEVICE_DETAIL_DATA) ::LocalAlloc(LPTR, requiredSize);
    
                if (detail)
                {
                    HANDLE hFile = INVALID_HANDLE_VALUE;
                    DWORD errCode = 0;
    
                    detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
    
                    if (SetupDiGetDeviceInterfaceDetail(DeviceInfoSet,
                                                        &DeviceInfoData,
                                                        detail,
                                                        requiredSize,
                                                        NULL,
                                                        NULL) == TRUE)
                    {
                        if (*theDeviceName != _T('\0'))
                        {
                            if (_tcscmp(detail->DevicePath, theDeviceName) == 0)
                            {
                                result = TRUE;
                            }
                        }
                    }
                    ::LocalFree(detail);
                }
            }
    
            //Close the DeviceInfoSet
    
            SetupDiDestroyDeviceInfoList(DeviceInfoSet);
        }
    
        return result;
    }

从代码中的某个地方,我们调用了以下语句:

这里aControl是基类CHeadsetControl的对象

CHeadsetControl * aControl;

if (aControl->IsDevicePresent())

一旦我浏览了上面的代码片段,我就会有很多疑问。

  1. 我们只使用基类对象指针 (aControl) 来调用虚函数。那么这里使用虚函数概念有什么必要呢?

  2. 在这里,我们使用来自基类 (CHeadsetControl) 的派生类 (CHeadsetControlUSB)。但是我没有看到将派生类引用分配给基类指针对象的地方。那么这里使用虚函数概念有什么必要呢?

先感谢您。

标签: c++visual-c++

解决方案


推荐阅读