В Java все находится в форме класса.
Если вы хотите использовать любой объект, тогда у вас есть две фазы:
Пример:
Object a;
a=new Object();
То же самое для концепции массива
Item i[]=new Item[5];
i[0]=new Item();
Если вы не дают секцию инициализации, тогда возникает NullpointerException
.
Вы можете взять свою функцию как есть и обернуть ее. Я имею в виду один способ, который полностью инкапсулирует обертку, - это сделать вашу функцию статическим членом локального класса. Для демонстрации:
int countRecursive(int cancelCondition)
{
struct hidden {
static int countRecursive(int cancelCondition, int counter = 0) {
if(cancelCondition > 0)
{
return countRecursive(--cancelCondition, ++counter);
}
else
{
return counter;
}
}
};
return hidden::countRecursive(cancelCondition);
}
Локальные классы - изящная, но редко встречающаяся особенность C ++. Они обладают некоторыми ограничениями, но, к счастью, могут иметь статические функции-члены. Никакой код извне не может передать hidden::countRecursive
недействительный counter
. Это полностью под контролем countRecursive
.
Вы пытались использовать «статическую» переменную счетчика. Статические переменные инициализируются только один раз и являются наилучшими кандидатами для использования в качестве переменных счетчика.
Если вы можете использовать что-то еще, кроме бесплатной функции, я бы предложил использовать некоторый функтор для удержания счетчика, но в случае, если вы не можете, вы можете попытаться использовать что-то подобное, используя дружбу, чтобы сделать трюк: [ 111]
#include <memory>
class Counter;
int countRecursive(int cancelCondition, std::unique_ptr<Counter> counter = nullptr);
class Counter {
int count = 0;
private:
friend int countRecursive(int, std::unique_ptr<Counter>);
Counter() = default; // the constructor can only be call within the function
// thus nobody can provide one
};
int countRecursive(int cancelCondition, std::unique_ptr<Counter> c)
{
if (c == nullptr)
c = std::unique_ptr<Counter>(new Counter());
if(cancelCondition > 0)
{
c->count++;
return countRecursive(--cancelCondition, std::move(c));
}
else
{
return c->count;
}
}
int main() {
return countRecursive(12);
}
Один из способов сделать это - использовать функтор. Вот простой пример:
#include <iostream>
class counter
{
public:
unsigned operator()(unsigned m, unsigned n)
{
// increment the count on every iteration
++count;
// rest of the function
if (m == 0)
{
return n + 1;
}
if (n == 0)
{
return operator()(m - 1, 1);
}
return operator()(m - 1, operator()(m, n - 1));
}
std::size_t get_count() const
{
return count;
}
private:
// call count
std::size_t count = 0;
};
int main()
{
auto f = counter();
std::cout << "Result: " << f(4, 0) << "\nNumber of calls: " << f.get_count() << std::endl;
return 0;
}
Вывод:
Result: 13
Number of calls: 107
Поскольку счет хранится в самом объекте, пользователь не может перезаписать его.
Вы можете инкапсулировать counter
:
struct counterRecParam {
counterRecParam(int c) : cancelCondition(c),counter(0) {}
private:
int cancelCondition;
int counter;
friend int countRecursive(counterRecParam);
};
Теперь вызывающая сторона не может изменить счетчик, и вам нужно лишь слегка изменить функцию:
int countRecursive(counterRecParam crp)
{
if(crp.cancelCondition > 0)
{
--crp.cancelCondition;
++crp.counter;
return countRecursive(crp);
}
else
{
return crp.counter;
}
}
И неявная преобразование позволяет вам позвонить с помощью int
counterRecursive(5);