24

Вопрос по c++ – Когда объект «выходит за рамки»?

В C ++, когда объект определяется как «вне области видимости»?

Более конкретно, если бы у меня был односвязный список, что бы определить один объект узла списка как «вне области видимости»? Или, если объект существует и на него ссылается переменнаяptrПравильно ли говорить, что объект определен как «вне области видимости»? момент, когда ссылка удалена или указывает на другой объект?

ОБНОВЛЕНИЕ: Предполагая, что объект является классом, у которого есть реализованный деструктор. Будет ли деструктор называться в тот момент, когда объект выходит из области видимости?

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;
}

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

Node* list_1 = new Node (3);

?

Ваши вопросы об обновлении очень хорошие, и ответ - нет. Когда указатель выходит из области видимости, деструктор объекта, на который он указывает,not автоматически вызывается. Вы должны назвать это сами, и это происходит, когда вы звонитеdelete на узле, чтобы освободить память. Об этом следует помнить, когда у вас есть массив или список указателей на объекты с осмысленными реализациями деструкторов. К счастью, так как вы должныfree в любом случае, вы сами будете запускать деструкторы.

от sparc_spread

Я должен был сказатьdelete вместоfree, игнорироватьfreeЭто наследие. Использовать толькоnew а такжеdelete для выделения / удаления кучи.

от sparc_spread

Кстати, если вам действительно нужен связанный список для чего-то, вам гораздо лучше использовать std :: list, чем свой собственный связанный список.

от DSimon
5 ответов
5

Code:

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

Когда он выходит за рамки, в которых он был объявлен :)

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

void Foo()
{
    int i = 10;

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

} // i is out of scope
2

& quot

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

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

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

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

; Выход за пределы ; не очень точный, но короткий и каждый понимает, что это значит.

44

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

on the stack или наon the heap.

Фрейм стека (или область) определяется оператором. Это может быть как функция, или как блок управления потоком (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 ключевое слово. Деструктор объекта кучи не вызывается, пока вы не освободите объект.

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

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

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

Вот пример создания материала в куче и выхода корневого указателя из области видимости:

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

Error: User Rate Limit ExceededwillError: User Rate Limit Exceeded

от 

A stack frame (or scope) is defined by a {} pair,Error: User Rate Limit Exceeded{}Error: User Rate Limit Exceededideone.com/oIqwdW

от 

Error: User Rate Limit Exceeded

от 

Error: User Rate Limit ExceedednextError: User Rate Limit Exceeded

от 

Error: User Rate Limit Exceeded

от Pat Murray
2

Объект

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

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.

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

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

Error: User Rate Limit Exceededstd::unique_ptr<Node> p = new Node;Error: User Rate Limit ExceededpError: User Rate Limit Exceeded

от 

Error: User Rate Limit ExceededwillError: User Rate Limit Exceeded

от 

Error: User Rate Limit Exceeded

от Pat Murray

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