Конструктор прерывает построение - PullRequest
2 голосов
/ 26 октября 2009

Я хотел бы, чтобы конструктор прерывал конструкцию объекта всякий раз, когда встречается определенный код ошибки (например, если встречается следующее):

CudaObj::CudaObj(InsertionSim *theSim)
{
    // Setup
    if(cublasInit() == CUBLAS_STATUS_NOT_INITIALIZED) {
        printf("CUBLAS init error.\n");
        return -1;  // abort here rather than return a value
    }

        ...
}

Какой самый простой способ достичь этого? Это будет обработка исключений?

Ответы [ 5 ]

16 голосов
/ 26 октября 2009

Я думаю, что идиоматический способ - выбросить исключение из конструктора, чтобы подчеркнуть, что объект не находится в допустимом состоянии.

1 голос
/ 26 октября 2009

Хотя я предпочитаю исключения, если у меня нет ОЧЕНЬ веских причин не делать этого, у исключений могут быть некоторые недостатки. В этой статье перечислены некоторые недостатки и несколько альтернатив обработке исключений.
Даже если вы используете только исключения для обработки ошибок, я все равно рекомендую прочитать их.

Еще одна вещь: IMO, вы не должны ограничивать свои соображения ошибками конструктора. поддержание двух разных инфраструктур обработки ошибок в одной системе сложно и подвержено ошибкам. Попробуйте выбрать метод обработки ошибок для всей системы.
хотя обработка ошибок конструктора является важным фактором при принятии этого решения, она не единственная.

1 голос
/ 26 октября 2009

Обработка исключений определенно была бы моим выбором, особенно в показанном выше случае, который действительно является исключением для правильного выполнения программы. В качестве альтернативы, вы можете позволить конструктору вернуться и иметь функцию IsInitilized () или что-то подобное, что позволит вам / пользователю проверить, что оно выполнено надлежащим образом. Это, однако, налагает дополнительное бремя на пользователя вашего класса, поскольку, как говорится, вы могли бы также использовать обработку исключений, поскольку это - общепринятый способ наложения этого бремени (они должны поймать исключение).

0 голосов
/ 26 октября 2009

Используйте исключение, если только у вас нет причины, по которой вы не используете исключения в своей программе. Причина в том, что, используя исключение, вы предотвращаете когда-либо конструктор объекта, считая объект действительным.

Ваш другой выбор - использовать метод IsInitialized (который будет возвращать false в случае сбоя конструктора) или тривиальный (пустой) конструктор и отдельный метод Initialize, который может возвращать код ошибки. Эти стратегии хороши, если вы избегаете исключений, и могут быть полезны в ситуациях, когда вы включаете код C ++ в более старый код C.

0 голосов
/ 26 октября 2009

Если вы не хотите использовать исключения (хотя по общему признанию, я использую в этой ситуации), вы можете создать статический метод для класса, в котором вы спрашиваете: «Могу ли я построить объект с этими параметрами?» и требуют, чтобы этот метод был вызван перед созданием. Таким образом, ваш конструктор станет

CudaObj::CudaObj(InsertionSim *theSim)
{
    // Setup
    ASSERT(cublasInit() == CUBLAS_STATUS_NOT_INITIALIZED)    
        ...
}

А потом тебе понадобится

BOOL CudaObj::CanConstruct(InsertionSim *theSim)
{
    // Check if we can construct
    return TRUE; // Or FALSE
}

Таким образом, ваш код будет

if (CudaObj::CanConstruct(pSim))
{
    pObj = new CudaObj(pSim);
}
else
{
    // Handle invalid parameter
    ...
}

Вы также можете предоставить удобный метод для выполнения обоих действий (например, с использованием аргументов OUT).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...