0

I have a good knowledge on Virtual Function concept. And can able to create a virtual function sample program and can explain it in detail.

But When I see the real time project i am getting confused about the way it is implemented.

Below is the virtual function implementation. And i am confused with the below implementation because might be i am missing something here.

Can anyone please explain the below implementation?

In the base class CHeadsetControl "IsDevicePresent" pure virtual function is implemented like as shown below:

HeadsetControl.h

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

We derive a class CHeadsetControlUSB from CHeadsetControl class like as shown below:

HeadsetControlUSB.h

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

IsDevicePresent() implementation from CHeadsetControlUSB class is like as shown below:

HeadsetControlUSB.cpp

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

Here "theHeadsetDevice" is the object of class "CHeadsetDevice". And CHeadsetDevice class is like as shown below:

CHeadsetDevice class implementation is like as shown below:

HeadsetDevice.h

Here If we see the below CHeadsetDevice class, it is not derived from CHeadsetControlUSB class. But it is using CHeadsetControlUSB class.

If we use CHeadsetControlUSB class like as shown below then what does it mean?

class CHeadsetControlUSB;

class HEADSETDEVICE_API CHeadsetDevice 
{

BOOL      IsDevicePresent() const;

};

IsDevicePresent() is implemented in HeadsetDevice.cpp like as shown below:

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

And from somewhere in the code we are calling the below statement:

Here aControl is the object of the base class CHeadsetControl

CHeadsetControl * aControl;

if (aControl->IsDevicePresent())

Once I have gone through the above code snippet, I have many doubts in my mind.

  1. Using only the base class object pointer (aControl) we are calling the virtual function. Then what is the necessity of using virtual function concept here?

  2. Here we are using derived class (CHeadsetControlUSB) from the base class (CHeadsetControl). But no where i didn't see of assigning derived class reference to the base class pointer object. Then what is the necessity of using virtual function concept here?

Thank you In advance.

sas
  • 19
  • 4
  • Possible duplicate of [Why do we need virtual functions in C++?](https://stackoverflow.com/questions/2391679/why-do-we-need-virtual-functions-in-c) – Miles Budnek Jun 08 '19 at 18:20
  • The answer to your question (1) is "That's what virtual functions are for; dispatching calls to the base class function to the right derived class function". As for (2), you cannot create an object of a class with a pure-virtual function, so `aControl` _must_ point to some derived class object. – Miles Budnek Jun 08 '19 at 18:24
  • You should look at [Interfaces in C++ (Abstract Classes)](https://www.tutorialspoint.com/cplusplus/cpp_interfaces.htm) – Chuck Walbourn Jun 08 '19 at 22:33
  • Please do not vandalize posted questions, including your own. Rolled back. – dxiv Jan 16 '21 at 04:56

0 Answers0