Подтвердить что ты не робот

Когда объект "выходит за рамки"?

В С++, когда объект определяется как "вне сферы действия"?

В частности, если бы у меня был один связанный список, что бы определить единственный объект node как "вне области видимости"? Или, если объект существует и ссылается на переменную "ptr", правильно ли утверждать, что объект определен как "вне области действия" в момент удаления ссылки или указывает на другой объект?

UPDATE: Предполагая, что объект - это класс, у которого есть реализованный деструктор. Будет ли деструктор вызываться в тот момент, когда объект выходит из области?

if (myCondition) {
    Node* list_1 = new Node (3);
    Node* list_2 = new Node (4);
    Node* list_3 = new Node (5);

    list_1->next = list_2;
    list_2->next = list_3;
    list_3->next = null;
}

Другими словами, если бы указатель node указывал, что list_1 вызывает его деструктор после этой строки:

Node * list_1 = new node (3);

?

4b9b3361

Ответ 1

Во-первых, помните, что объекты в С++ могут быть созданы либо в стеке, либо в куче.

Кадр стека (или область) определяется оператором. Это может быть как большой, так и небольшой, как блок управления потоком (while/if/for и т.д.). Произвольная пара {}, содержащая произвольный блок кода, также представляет собой стек стека. Любая локальная переменная, определенная в кадре, выйдет за пределы области действия, как только программа выйдет из этого кадра. Когда переменная стека выходит из области видимости, ее деструктор вызывается.

Итак, вот классический пример фрейма стека (выполнение функции) и локальная переменная, объявленная внутри него, которая выйдет за пределы области после выхода из фрейма стека - после завершения функции:

void bigSideEffectGuy () {
    BigHeavyObject b (200);
    b.doSomeBigHeavyStuff();
}
bigSideEffectGuy();
// a BigHeavyObject called b was created during the call, 
// and it went out of scope after the call finished.
// The destructor ~BigHeavyObject() was called when that happened.

Вот пример, где мы видим, что стек стека является только телом оператора if:

if (myCondition) {
    Circle c (20);
    c.draw();
}
// c is now out of scope
// The destructor ~Circle() has been called

Единственный путь для объекта, созданного стеком, "оставаться в области видимости" после выхода фрейма, является возвратным значением функции. Но это действительно не "остается в области видимости", потому что объект копируется. Таким образом, оригинал выходит за рамки, но копия сделана. Пример:

Circle myFunc () {
    Circle c (20);
    return c;
}
// The original c went out of scope. 
// But, the object was copied back to another 
// scope (the previous stack frame) as a return value.
// No destructor was called.

Теперь объект также может быть объявлен в куче. Ради этой дискуссии подумайте о куче как о аморфном блоке памяти. В отличие от стека, который автоматически выделяет и деблокирует необходимую память при входе и выходе из фреймов стека, вы должны вручную зарезервировать и освободить память кучи.

Объект, объявленный в куче, после моды "выживает" между кадрами стека. Можно сказать, что объект, объявленный в куче, никогда не выходит за рамки, но это действительно потому, что объект никогда не ассоциируется с какой-либо областью. Такой объект должен быть создан с помощью ключевого слова new и должен называться указателем.

Вы несете ответственность за освобождение объекта кучи, как только вы закончите с ним. Вы освобождаете объекты кучи с помощью ключевого слова delete. Деструктор объекта кучи не вызывается до тех пор, пока вы не освободите объект.

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

Подумайте об этом так: объект, созданный в стеке, похож на воздушный шар, прикрепленный к стулу в комнате. Когда вы выходите из комнаты, воздушный шар автоматически появляется. Объект, созданный на куче, похож на воздушный шар на ленте, привязанный к стулу в комнате. Лента - это указатель. Когда вы выходите из комнаты, лента автоматически исчезает, но воздушный шар просто плывет к потолку и занимает пространство. Правильная процедура состоит в том, чтобы вытащить воздушный шар с помощью штифта, а затем выйти из комнаты, после чего лента исчезнет. Но, хорошая вещь о воздушном шаре на струне, вы также можете развязать ленту, держать ее в руке и выйти из комнаты и взять с собой воздушный шар.

Итак, перейдите к примеру связанного списка: обычно узлы такого списка объявляются в куче, причем каждый node содержит указатель на следующий node. Все это сидит на куче и никогда не выходит за рамки. Единственное, что может выйти из области видимости - указатель, указывающий на корень списка - указатель, который вы используете для ссылки в списке в первую очередь. Это может выйти из сферы действия.

Здесь приведен пример создания материала в куче и указатель root, выходящий из области видимости:

if (myCondition) {
    Node* list_1 = new Node (3);
    Node* list_2 = new Node (4);
    Node* list_3 = new Node (5);

    list_1->next = list_2;
    list_2->next = list_3;
    list_3->next = null;
}
// The list still exists
// However list_1 just went out of scope
// So the list is "marooned" as a memory leak

Ответ 2

{ //scope is defined by the curly braces
    std::vector<int> vec;
}
// vec is out of scope here!
vec.push_back(15);

Ответ 3

"Вне области охвата" является метонимией: как в, используя имя или терминологию одного понятия, чтобы говорить о чем-то близком, но другом.

В С++ область действия - это статическая область текста программы, и поэтому что-то "вне сферы действия" , взятое буквально, означает физически за пределами области текста. Например, { int x; } int y;: объявление y выходит за пределы области видимости x.

Метонимия "выход из сферы действия" используется для выражения идеи о том, что динамическая активация/создание экземпляра среды, связанной с некоторой областью действия, заканчивается. И поэтому переменные, определенные в этой области, уходят (таким образом, "вне сферы действия" ).

То, что на самом деле ушло "вне сферы действия" , является указателем инструкции, так сказать; оценка программы в настоящее время происходит в области, которая не имеет видимости для этого. Но не все в масштабах уходит! Статические переменные все еще будут присутствовать при следующем вводе области.

"Выход из сферы действия" не очень точен, но короткий, и все понимают, что это значит.

Ответ 4

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

void some_func() {
  std::string x("Hello!");
  // x is in scope here
}
// But as soon as some_func returns, x is out of scope

Это относится только к материалам, объявленным в стеке, поэтому он имеет мало общего с односвязными списками, поскольку узлы списка обычно создаются в куче с помощью new.

В этом примере указатель, возвращаемый new, выходит из области действия, когда функция завершается, но ничего не произойдет с самим Node:

void make_a_node() {
  Node* p = new Node;
} // Oh noes a memory leak!

Ответ 5

Когда он покидает область видимости, указанную в:)

Ваш вопрос в его нынешнем виде не отвечает, не видя реализации. Это сводится к тому, что вы объявляете этот node.

void Foo()
{
    int i = 10;

    {
        int j = 20;
    } // j is out of scope

} // i is out of scope