2016-02-15 2 views
0
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); 
} 

Я переписываю свою программу, используя списки инициализации членов, я надеюсь, что код выше правильный, хотя это первый раз, когда я использовал списки инициализации членов.Правильно ли это ctor/использование ctor?

Я понял, что позже, в родительском классе этого класса: я создал другую копию копии для создания (Instantiate, я думаю) списка. Когда все, что я думаю, что мне было нужно:

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

Это кажется слишком простым и склонным к ошибкам верификации бы этот пример работа, и как мне делать простые проверки в инициализации учетной записи? Из того, что я понимаю, список инициализации членов может выполнять логические операторы if (X? A: B), хотя я не могу понять, как я буду проверять ввод.

EDIT: Я CTOR по умолчанию и перегружен 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* 

{

}

+0

ну, это список инициализации членов, трудно комментировать его правильность, не видя больше соответствующего кода. Для записей с '({'\ 0'}), что несколько нетрадиционно; вы можете использовать здесь '{}' или даже встроить в определение класса. Магическое число '33' является красным флагом, вероятно, это должно быть какое-то выражение' sizeof' –

+0

Я не уверен, что вам нужен более подходящий код. Что касается размера WCHAR (ов), я знаю максимальный размер от winAPI (32 и 128), поэтому я просто предположил, что это нормально. –

+0

Что значит «от winAPI»? 'szDeviceName', предположительно, является членом массива этого класса, который вы написали сами. Возможно, определение класса содержит 'wchar_t szDeviceName [16];', читатели не знают. Возможно, позже во времени вы измените длину этого массива в определении класса и забудете изменить конструктор. Использование правильной длины, основанной на массиве, позволяет избежать возможности этих двух выходить из синхронизации, а также облегчает кому-то чтение кода, чтобы он знал, что он работает правильно. –

ответ

0

Это не должно быть необходимо для выполнения проверки в списке инициализации членов, и если вы необходимо выполнить проверки, вам, вероятно, нужно переосмыслить свой дизайн.

Давайте посмотрим на ваш класс:

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

Здесь мы можем увидеть довольно большую проблему, если lpMONITORINFOEX является nullptr. Похоже, ваш класс нуждается в, чтобы он функционировал. Задайте себе вопрос: могу ли я иметь класс SingleMonitorInfo без объекта MONITORINFOEX?

Если вашему классу нужен этот объект, сделайте это более ясным, передав ссылку!

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

Пользователи вашего класса больше не могут конструировать ваш объект неправильно. Если по какой-то причине lpMONITORINFOEX был необязательным, и необходимо, чтобы оставаться указатель, вы могли бы просто использовать тройной оператор ?:

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) 

Очевидно, что я не знаю, что ваши объекты, так что я просто предполагаю, ввод по умолчанию ,

+0

Спасибо за ваши наблюдения, я изменил его на const и передал ссылку. Вот почему я хотел проверить вход, но нет необходимости в том, что вы описали. Очень полезно. –

Смежные вопросы