问题
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