Вопрос об объеме локальной переменной

Могло бы быть слишком старым, но здесь мое решение для быстрого

class Recursion {
    func fibonacci(_ input: Int) {
        var dictioner: [Int: Int] = [:]
        dictioner[0] = 0
        dictioner[1] = 1
       print(fibonacciCal(input, dictioner: &dictioner))
    }

    func fibonacciCal(_ input: Int, dictioner: inout [Int: Int]) -> Int {
        if let va = dictioner[input]{
            return va
        } else {
            let firstPart = fibonacciCal(input-1, dictioner: &dictioner)

            let secondPart = fibonacciCal(input-2, dictioner: &dictioner)

            if dictioner[input] == nil {
                dictioner[input] = firstPart+secondPart
            }

            return firstPart+secondPart
        }
    }
}

// 0,1,1,2,3,5,8
class TestRecursion {
    func testRecursion () {
        let t = Recursion()
        t.fibonacci(3)
    }
}
8
задан Kirill V. Lyadvinsky 7 September 2009 в 00:36
поделиться

4 ответа

Вы правильно процитировали стандарт. Позвольте мне подчеркнуть:

имя , объявленное в блоке, является локальным для этого блока. Его потенциальная область действия начинается в точке объявления и заканчивается в конце декларативной области.

Фактически, вы не объявляли никакого имени . Ваша строка

MyClass (12345);

даже не содержит объявления ! Он содержит выражение, которое создает экземпляр MyClass, вычисляет выражение (однако в данном конкретном случае вычислять нечего), приводит его результат в void и уничтожает созданные там объекты.

Менее запутанная вещь будет звучать так, как будто

call_a_function(MyClass(12345));

Вы видели это много раз и знаете, как это работает, не так ли?

4
ответ дан 3 November 2019 в 13:09
поделиться

Объект, созданный в вашем

MyClass(12345);

, является временным объектом, который является живым только в этом выражении ;

MyClass m(12345);

- это объект, который активен для всего блока.

16
ответ дан 3 November 2019 в 13:09
поделиться

Фактически вы создаете объект, не сохраняя его в области видимости, поэтому он уничтожается сразу после создания. Отсюда и такое поведение.

Вы не можете получить доступ к созданному объекту, так зачем компилятору хранить его?

8
ответ дан 3 November 2019 в 13:09
поделиться

Чтобы ответить на другие ваши вопросы. Ниже приводится вызов оператора запятой. Он создает временный MyClass , который включает вызов его конструктора. Затем он вычисляет второе выражение cout << "Y" << endl , которое выводит Y. Затем, в конце полного выражения, он уничтожает временное, которое вызывает его деструктор. Итак, ваши ожидания оправдались.

MyClass (12345), cout << "Y" << endl;

Чтобы следующее работало, вы должны добавить круглые скобки, потому что запятая имеет предопределенное значение в объявлениях. Он начнет объявлять функцию some_func , возвращающую int и не принимая никаких параметров, и назначит объект scoped_lock для x . Используя круглые скобки, вместо этого вы говорите, что все это представляет собой одно выражение оператора запятой.

int x = (boost::scoped_lock (my_mutex), some_func()); // still multi-thread safe

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

boost::scoped_lock(my_mutex);
boost::scoped_lock my_mutex;

Я видел неправильное использование терминов «область действия» и «время жизни».

  • Область - это место, где вы можете ссылаться на имя, не уточняя его. Имена имеют области действия, а объекты наследуют область действия имени, используемого для их определения (таким образом, иногда в Стандарте говорится «локальный объект»). Временный объект не имеет области видимости, потому что у него нет имени. Точно так же объект, созданный new , не имеет области действия. Область видимости - это свойство времени компиляции. Этот термин часто неправильно используется в Стандарте, см. этот отчет о дефектах , поэтому довольно сложно найти реальное значение.

  • Время жизни - это свойство времени выполнения. То есть, когда объект настроен и готов к эксплуатации. Для объекта типа класса время жизни начинается, когда конструктор завершает выполнение, и заканчивается, когда деструктор начинает выполнение. Срок службы часто путают со сферой действия, хотя это совершенно разные вещи.

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

5
ответ дан 3 November 2019 в 13:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: