Страница 1 из 3
Занимательная задачка: однократный вызов
Добавлено: 07 ноя 2015, 15:17
Romeo
Есть некая функция. Она состоит из двух участков кода
CodeA и
CodeB, которые никак не связаны друг с другом общими переменным и не требуют никаких дополнительных параметров.
Функция вызывается из нескольких мест программы.
После изменений требований клиентами, архитектор создал таску на изменение кода - участок
CodeA отныне должен отрабатывать только при первом вызове функции.
Таску просмотрели два программиста. Один С-шник, второй С++-ник. С-шник сразу сразу выдал решение:
Код: Выделить всё
void Function()
{
static int isFirstCall = 1;
if (isFirstCall)
{
<CodeA>
isFirstCall = 0;
}
<CodeB>
}
С++-ник подумал, и сказал своему коллеге: "Не лезь ты со своим С в наш код". А потом добавил: "Я смогу реализовать новые требования и без условия с проверкой статического флажка".
Указать наиболее простое решение, которое могло быть предложено С++ программистом. Использовать С++ версии 03 (без 11-го стандарта).
Re: Занимательная задачка: однократный вызов
Добавлено: 07 ноя 2015, 15:37
Сионист
Код: Выделить всё
class A
{
A ()
{
<CodeA>
};
};
void Function()
{
static A a;
<CodeB>
}
Re: Занимательная задачка: однократный вызов
Добавлено: 07 ноя 2015, 16:10
Romeo
Верное направление. Господа, кто хочет прокомментировать предложенное решение? Что бы вы поменяли здесь и из каких соображений?
Re: Занимательная задачка: однократный вызов
Добавлено: 09 ноя 2015, 11:11
Romeo
Раз все молчат, пишу окончательное решение.
Сионист выбрал верный подход, однако в его решении три проблемы:
1. Код не скомпилируется, так как конструктор расположен в приватной секции класса;
2. Нарушена инкапсуляция функции. До этого
CodeA никак нельзя было вызвать отдельно. В новом же варианте кто угодно сможет создать класс
A, таким образом вызвав
CodeA;
3. Ну и ещё одна косметическая правка - имя класса. Всё-таки имя
A не для коммерческого кода.
Код: Выделить всё
void Function()
{
class CCaller
{
public:
CCaller()
{
<CodeA>
}
};
static CCaller singleCall;
<CodeB>
}
Re: Занимательная задачка: однократный вызов
Добавлено: 09 ноя 2015, 18:55
Сионист
Ну и ещё одна косметическая правка - имя класса. Всё-таки имя A не для коммерческого кода.
Это же только пример.
Re: Занимательная задачка: однократный вызов
Добавлено: 10 ноя 2015, 15:36
Decoder
Я думаю лучше всё же оставить конструктор класса приватным, чтобы его не мог вызвать кто угодно, а вызывающую функцию сделать дружественной для этого класса...
Код: Выделить всё
void Function();
class CCaller
{
CCaller()
{
<Code A>
}
friend void Function();
};
void Function()
{
static CCaller singleCall;
<Code B>
}
Re: Занимательная задачка: однократный вызов
Добавлено: 10 ноя 2015, 15:58
Romeo
Если класс спрятан внутри функции, его уже никто не увидит снаружи, и тем более не вызовет. Это более строгое ограничение, чем приватный конструктор внешнего класса.
Re: Занимательная задачка: однократный вызов
Добавлено: 11 ноя 2015, 18:09
WinMain
Код: Выделить всё
void Function()
{
static std::vector<int> v(1);
try
{
v.at(0);
v.clear();
<Code A>
}
catch(std: :o ut_of_range& ex)
{
}
<Code B>
}
Re: Занимательная задачка: однократный вызов
Добавлено: 12 ноя 2015, 11:35
Romeo
Не одобряю головоломные и неочевидные решения. А так же крайне негативно отношусь к построению программной логики на обработке исключений. Исключения должны использовать только для обработки ошибок!
Но в качестве "а посмотрите как круто можно извернуться" - это, бесспорно, очень занимательный вариант

Re: Занимательная задачка: однократный вызов
Добавлено: 12 ноя 2015, 11:46
Romeo
Кстати, если уж пошла такая пьянка, ещё одно решение. Класса нет, но зато используется C++11, который в первоначальном условии был запрещён.
Код: Выделить всё
void Function()
{
static int fake = []() -> int
{
<CodeA>
return 0;
}();
<CodeB>
}