Is this ctor / use of ctor correct?

谁都会走 提交于 2019-12-12 03:33:07

问题


    SingleMonitorInfo::SingleMonitorInfo(MONITORINFOEX* lpMONITORINFOEX)
    :rcMonitorArea(lpMONITORINFOEX->rcMonitor),
    rcWorkArea(lpMONITORINFOEX->rcWork),
    dwStatusFlags(lpMONITORINFOEX->dwFlags),
    szDeviceName({ '\0' }),
    szMonitorName({ '\0' }),
    szMonitorDescription({ '\0' }),
    lpPixelArray(NULL)
{
    wcscpy_s(SingleMonitorInfo::szDeviceName, 33, lpMONITORINFOEX->szDevice);
    SingleMonitorInfo::setStringMonitorNameAndDescription(lpMONITORINFOEX->szDevice);
}

I am rewriting my program using member initialisation lists, I hope the code above is correct, although this is the first time I've used member initialisation lists.

I realised that later on, in a parent of this class: I was creating another copy, of a copy to create (Instantiate I think) the list. When all I think I needed was:

for (int i = 0; i < lpMonitorList->iMaximumSize; i++)
    {
        smiMonitorList[i] = SingleMonitorInfo(&lpMonitorList->infoArray[i]);
    }

It seems too simple and prone to verification errors, would this example work, and how to I do simple checks in the member initialisation? From what I understand the member initialisation list can do logical if statements ( X ? A : B ), though I cannot fathom how I would verify input.

EDIT: I have a default ctor and overloaded for MONITORINFOEX

SingleMonitorInfo::SingleMonitorInfo()
:dMaxPercentDifference(1), // Double
iCheckTaskbar(1), // int
rcMonitorArea(RECT{ 0, 0, 0, 0 }), // RECT
rcWorkArea(RECT{ 0, 0, 0, 0 }), // RECT
dwStatusFlags(DWORD(0x00000000)), // DWORD
dwCapabilitiesFlags(DWORD(0x00000000)), // DWORD
szDeviceName({ '\0' }), // String (WCHAR)
szMonitorName({ '\0' }), // String (WCHAR)
szMonitorDescription({ '\0' }), // String (WCHAR)
lpPixelArray(NULL) // unsigned char*

{

}


回答1:


It shouldn't be necessary to perform checks in your member initializer list, and if you need to perform checks, you probably need to rethink your design.

Let's look at your class:

SingleMonitorInfo::SingleMonitorInfo(MONITORINFOEX* lpMONITORINFOEX)
:rcMonitorArea(lpMONITORINFOEX->rcMonitor),
rcWorkArea(lpMONITORINFOEX->rcWork),
dwStatusFlags(lpMONITORINFOEX->dwFlags),
szDeviceName({ '\0' }),
szMonitorName({ '\0' }),
szMonitorDescription({ '\0' }),
lpPixelArray(NULL)

Here we can see a pretty big problem if lpMONITORINFOEX is nullptr. It looks like your class needs it to function though. Ask yourself: could I have a SingleMonitorInfo class without a MONITORINFOEX object?

If your class needs that object, make it more explicit by passing a reference!

SingleMonitorInfo::SingleMonitorInfo(const MONITORINFOEX& lpMONITORINFOEX)
:rcMonitorArea(lpMONITORINFOEX.rcMonitor),
rcWorkArea(lpMONITORINFOEX.rcWork),
dwStatusFlags(lpMONITORINFOEX.dwFlags),
szDeviceName({ '\0' }),
szMonitorName({ '\0' }),
szMonitorDescription({ '\0' }),
lpPixelArray(NULL)

Users of your class can no longer construct your object incorrectly. If for some reason lpMONITORINFOEX was optional, and needed to remain a pointer, you could simply use the ternary operator ?:

SingleMonitorInfo::SingleMonitorInfo(MONITORINFOEX* lpMONITORINFOEX)
:rcMonitorArea(lpMONITORINFOEX ? lpMONITORINFOEX->rcMonitor : nullptr),
rcWorkArea(lpMONITORINFOEX ? lpMONITORINFOEX->rcWork : false),
dwStatusFlags(lpMONITORINFOEX ? lpMONITORINFOEX->dwFlags : 0),
szDeviceName({ '\0' }),
szMonitorName({ '\0' }),
szMonitorDescription({ '\0' }),
lpPixelArray(NULL)

Obviously I don't know what your objects are, so I'm just guessing default input.



来源:https://stackoverflow.com/questions/35401261/is-this-ctor-use-of-ctor-correct

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!