Необязательная обработка ошибок - PullRequest
2 голосов
/ 15 марта 2011

У меня есть метод создания, как показано ниже, в котором я хочу (если возвращаемое значение является нулевым указателем) получить ошибку. Однако я хочу, чтобы эта обработка ошибок была необязательной, а не требованием при вызове функции.

код:

class foo {
    foo() {...};
public:
    ~foo();
    static foo* createFoo(int aparam = 42, int bparam = 10, int& error = ?) {
        afoo* = new foo();
        if (!afoo) {
            error = 11;
            return 0; //NULL
        }
        ...
        return afoo;
    }

}

Таким образом, я могу решить, использовать ли:

foo* myfoo = createFoo(42);
if (!myfoo) { ... }

Или

int errorcode = 0;
foo* myfoo = createFoo(42, 10, errorcode);
...

На данный момент (в моем реальном коде) я просто использую нулевой указатель (вместо ссылки) и определяю его действительность в коде createFoo перед тем, как выдавать ошибку.

Меня интересует лучшая практика для этой ситуации .

Ответы [ 2 ]

1 голос
/ 15 марта 2011

Я не знаю, что могу предложить лучшую практику , но вот моя точка зрения.

Проверка на NULL (неудачное размещение) является стандартной практикой в ​​C и C ++, этохорошо понятная и легко узнаваемая идиома.Добавление дополнительного кода ошибки, в то же время обеспечивая гибкость, также добавляет, возможно, ненужную сложность.Вызывающим абонентам приходится решать, будут ли они использовать параметр.

Зачем им использовать параметр, если они не чувствуют, что он может выйти из строя в этом месте?Как бы

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

// Returns error code.
static int createFoo(int, int, Foo **);

Это, возможно, менее удобная функция, но подталкивает вызывающего (пользователя)в правильном направлении.

В качестве альтернативы, вы можете использовать исключения, либо гарантируя, что выдается std :: bad_alloc, либо выбрасывая исключение вашего собственного создания с соответствующим кодом ошибки.Казалось бы, это самая чистая подпись:

struct fooException { int error; }

// Throws fooException if cannot create foo.
static foo * createFoo(int, int);

Философия, которой я руководствуюсь: минимизировать сложность.В этом случае, удалив то, что кажется посторонним вариантом.Либо код ошибки является значимым и должен использоваться всегда , либо он является посторонним и всегда будет игнорироваться.

1 голос
/ 15 марта 2011

Когда вы передаете что-то по ссылке, вы говорите пользователю этой функции, что это обязательный параметр.Если вы хотите сделать код ошибки необязательным, передайте указатель на int и установите его значение по умолчанию в null.

static foo* createFoo(int aparam = 42, int bparam = 10, int* error = NULL)
...