Как стать автором
Обновить
1
0

Пользователь

Отправить сообщение
Здесь следовало бы либо вызвать delete, либо хотя бы отдать хранящийся в переменной interface адрес наружу в любом случае, чтобы об этом мог позаботиться вызывающий код

а ещё лучше — std::unique_ptr::release
И, да, ребята, категорически умоляю, прячьте объяснения под кат, а то совсем неинтересно становится читать
Ну вот не нравится многим C++-сникам goto, не любят они его вплоть до включения в coding style запрета на goto.

Исходный вариаент кода — плох многословностью, copy-paste-ом, множественными return.

Вариант с несколькими уровнями вложенности — да, если их больше 2-х это напрягает, хотя, на мой вкус, всё равно читается лучше, чем то, что было изначально.

Вариант с одним if-ом — плох тем, что даёт, пусть и небольшие, лишние накладные расходы на создание неиспользуемых объектов.

Ещё варианты есть? По-моему, альтернативы нет.
Ну, погуглите one return only, будет много интересного. И, да, я не считаю это большой проблемой в исходном варианте, гораздо хуже там неоднократный copy-paste блока после if.
А если везде возвращать один результат, то это уже нарушение DRY. Собственно, исходный вариант и есть хороший пример нарушения DRY
К сожалению, не раскрыта тема (анти?)паттерна null-object, а по крайней мере в одном популярном фреймворке он просто-таки красной нитью…
З.Ы. в исходном варианте множественный return == антипаттерн
В C ему альтернатива ровно одна: goto. Если есть другие варианты, то их, пожалуйста, в студию.
Он читается лучше, т.к. при чтении банально меньше нужно елозить глазами вниз по экрану. И антипаттерн он только в C++, в «чистом» C, где широко используются коды ошибок, это — обычное дело. Конечно, больше 3-х уровней отступов нормальные люди без острой необходимости не делают.

P.S. «Антипаттерн» — обычное слово-идеон. Причисление к паттернам и антипаттернам, как правило, происходит на волне очередного хайпа. В своё время что только не объявляли антипаттерном: коды возврата, null-объекты, goto, более одного return, отсутствие Yoda-style в сравнении. А оказалось, что и коды возврата, и null-объект — вполне рабочие подходы, goto широко используется в системном программировании на C для обработки ошибок, yoda-style используют не только лишь не все, а вообще мало кто.
Ну и зачем писать вот так:
    std::string aStr;
    int ok = readLine(aStr);
    if (!ok) {
        processError();
        return;
    }

    std::string bStr;
    ok = readLine(bStr);
    if (!ok) {
        processError();
        return;
    }

    int a = 0;
    ok = parseInt(aStr, a);
    if (!ok) {
        processError();
        return;
    }

    int b = 0;
    ok = parseInt(bStr, b);
    if (!ok) {
        processError();
        return;
    }

    int result = 0;
    ok = safeAdd(a, b, result);
    if (!ok) {
        processError();
        return;
    }

    std::cout << result << std::endl;


«Лапшу» можно с любым механизмом обработки ошибок сотворить. А если вот так:
std::string aStr;

if (readLine(aStr))
{
    std::string bStr;

    if (readLine(bStr))
    {
        int a = 0, b = 0;

        if (parseInt(aStr, a) && parseInt(bStr, b) && safeAdd(a, b, result))
        {
            std::cout << result << std::endl;

            return;
	}
    }
}

processError();

Или даже так — ценой, возможно, преждевременного создания объектов (надеюсь, компиляторы/библиотеки, когда-нибудь станут достаточно умными, чтобы сделать это чуть-чуть дешевле:
std::string aStr, bStr;
int a, b, result;

if (
    readLine(aStr) && readLine(bStr) &&
    parseInt(aStr, a) && parseInt(bStr, b) && 
    safeAdd(a, b, result)
)
    std::cout << result << std::endl;
else
    processError();
Это мнение Саттера, как частного лица. Если бы это было мнение комитета по стандартизации, это было бы в стандарте. Мотивировка — откровенно слабая:
So as soon as any of the special functions is declared, the others should all be declared to avoid unwanted effects like turning all potential moves into more expensive copies, or making a class move-only.

Т.е. запрещайте, чтобы избежать неких «нежелательных эффектов». А никаких эффектов и без вмешательства кодера не будет, поведение компилятора в этом случае выглядит вполне разумным. Ну и традиционное, как пьяный дед мороз под новый год, «explicit is better than implicit»:
Defining only the move operations or only the copy operations would have the same effect here, but stating the intent explicitly for each special member makes it more obvious to the reader.


P.S. лично я предпочитаю не загаживать исходный код вещами, ничего не дающими ни кодеру, ни компилятору
class X
{
public:
    X(const X&) = delete;
    X& operator=(const X&) = delete;
    X(X&& src) noexcept;
    X& operator=(X&& src) noexcept;
// ...
};


Запрещать копирование не нужно, т.к. при наличии перемещающих конструктора и оператора присвоения компилятор не станет генерировать их копирующие аналоги.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность