如果是对象“超出范围”?如果是对象“超出范围”?(When is an object “out of

2019-05-13 11:29发布

在C ++中,当一个对象定义为“超出范围”?

更具体地讲,如果我有一个单向链表,你会定义一个列表节点对象为“超出范围”? 或者,如果一个对象存在并正在由一个变量引用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;
}

换句话说,将节点被指向list_1调用此行后其析构函数:

Node* list_1 = new Node (3);

Answer 1:

First, remember that objects in C++ can be created either on the stack or on on the heap.

A stack frame (or scope) is defined by a statement. That can be as big as a function or as small as a flow control block (while/if/for etc.). An arbitrary {} pair enclosing an arbitrary block of code also constitutes a stack frame. Any local variable defined within a frame will go out of scope once the program exits that frame. When a stack variable goes out of scope, its destructor is called.

So here is a classic example of a stack frame (an execution of a function) and a local variable declared within it, which will go out of scope once the stack frame exits - once the function finishes:

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.

Here is an example where we see a stack frame being just the body of an if statement:

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

The only way for a stack-created object to "remain in scope" after the frame is exited is if it is the return value of a function. But that is not really "remaining in scope" because the object is being copied. So the original goes out of scope, but a copy is made. Example:

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.

Now, an object can also be declared on the heap. For the sake of this discussion, think of the heap as an amorphous blob of memory. Unlike the stack, which automatically allocates and de-allocates the necessary memory as you enter and exit stack frames, you must manually reserve and free heap memory.

An object declared on the heap does, after a fashion, "survive" between stack frames. One could say that an object declared on the heap never goes out of scope, but that's really because the object is never really associated with any scope. Such an object must be created via the new keyword, and must be referred to by a pointer.

It is your responsibility to free the heap object once you are done with it. You free heap objects with the delete keyword. The destructor on a heap object is not called until you free the object.

The pointers that refer to heap objects are themselves usually local variables associated with scopes. Once you are done using the heap object, you allow the pointer(s) referring to it to go out of scope. If you haven't explicitly freed the object the pointer is pointing to, then the block of heap memory will never be freed until the process exits (this is called a memory leak).

Think of it all this way: an object created on the stack is like a balloon taped to a chair in a room. When you exit the room, the balloon automatically pops. An object created on the heap is like a balloon on a ribbon, tied to a chair in a room. The ribbon is the pointer. When you exit the room, the ribbon automatically vanishes, but the balloon just floats to the ceiling and takes up space. The proper procedure is to pop the balloon with a pin, and then exit the room, whereupon the ribbon will disappear. But, the good thing about the balloon on the string is you can also untie the ribbon, hold it in your hand, and exit the room and take the balloon with you.

So to go to your linked list example: typically, nodes of such a list are declared on the heap, with each node holding a pointer to the next node. All of this is sitting on the heap and never goes out of scope. The only thing that could go out of scope is the pointer that points to the root of the list - the pointer you use to reference into the list in the first place. That can go out of scope.

Here's an example of creating stuff on the heap, and the root pointer going out of scope:

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


Answer 2:

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


Answer 3:

“超出范围”是一种转喻:如在使用的名称或一个概念的术语谈密切相关但不同的。

C ++中的范围是程序文本的静态区域,等等东西“超出范围”,字面上理解,物理装置的文本的区域的外侧。 例如, { int x; } int y; { int x; } int y; :声明y是出其范围的x是可见的。

转喻“走出去的范围”是用来表达的想法,与一些范围有关的环境的动态激活/实例被终止。 所以在该范围内定义的变量要离开(因此“超出范围”)。

什么实际上已经“超出范围”是指令指针,可以这么说; 该计划的评估目前正在进行中,没有知名度,是一个范围。 但是,在一个范围不是一切消失! 静态变量依然存在输入范围的下一次。

“走出去的范围”,是不是很准确,但短期和每个人都明白这意味着什么。



Answer 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会走出去的范围时,函数退出,但什么都不会发生在节点本身:

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


Answer 5:

当它离开的范围,它被宣布:)

因为它代表你的问题不是没有看到实施交代。 归结到一点,你声明这个节点。

void Foo()
{
    int i = 10;

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

} // i is out of scope


文章来源: When is an object “out of scope”?