C ++变量引用范围

时间:2015-07-10 16:09:43

标签: c++ scope

我在很长一段时间内第一次写了一些C ++并且记不起来了。我目前正在努力争取范围(以及何时使用指针与输入参数的引用)。具体来说,如果我在堆栈上创建了一些内容,它会保留多长时间?

如果我有一个简单的类:

()

然后我有一个简单的Person Generator方法和main:

class Person {
    const std::string name_;

public:
    Person(const std::string& name) : name_(name) {}
    const std::string& get_name() { return name_; }
};

在我删除之前,该人的名字是否已超出范围?

我知道我可以创建一个新的std :: string并将其传递给Person,但是我还有一个变量需要清理。标准是接受方法签名中的指针或引用吗?

此外,欢迎任何有关此主题的教程的参考。

5 个答案:

答案 0 :(得分:2)

这里没有问题。 Person的构造函数复制堆栈中的值。

答案 1 :(得分:2)

让我们分解一下:

Person* get_person() {
    std::string name = "Bob"; // 1)
    return new Person(name); // 2)
} // 3)
  1. 创建字符串名称

    此处字符串name在堆栈上创建。

  2. 在堆上创建新人

    我们必须查看构造函数以了解正在发生的事情

  3. class Person {
        const std::string name_; 
    public:
        Person(const std::string& name) : // 2.a)
            name_(name) // 2.b)
        {} // 2.c)
    
    }
    

    a)name通过引用传递。对name的引用存在于当前帧中,name存在于前一帧的堆栈中。

    b)name 复制name_。因为人是在堆上创建的,所以name_也存在于堆上。

    c)对name的引用被破坏,因为它的范围结束。

    1. 块结束,因此name超出范围。我们返回一个指向生成在堆上的Person的指针,因此Person - 其name_ - 不会被破坏。
    2. 最重要的一步是2.b)。这里,堆栈上的名称被复制构造到中。这是因为name_不是引用而是值,这使得它与传入的name“无关”。

      Tl; dr这个人的名字不会超出范围,因为只有堆栈上的值才能超出范围。在这种情况下,只有一个指向这个人的指针位于堆栈上,而这个人 - 以及它的名字 - 是在堆上创建的(通过new)并且不会超出范围。

答案 2 :(得分:1)

你的代码很好。

当您将对name的引用传递给构造函数时,构造函数将从中创建一个新字符串,即name_将是name的副本并放在堆中。

从get_person返回后,变量名称超出范围,但已经创建了副本。

所以 - 没问题。

来自http://www.cplusplus.com/reference/string/string/string/

copy (2): string (const string& str);

(2) copy constructor Constructs a copy of str.

答案 3 :(得分:1)

只要堆栈相关,堆栈上分配的东西就会保留在那里,并在弹出堆栈时立即销毁。

C ++倾向于采用两种方法从堆栈中获取数据:在堆上分配,使其持续时间超过当前堆栈范围,并进行复制。

您的name变量是一个堆栈分配的std::string,但是这会被复制到您分配的C ++对象,因为您通过引用传递它,而不是指针。

在内部,字符串数据本身可以在堆上分配,这就是这些容器经常工作的方式,但这并不是你真正关心的问题。

简而言之,堆栈对象在其范围的持续时间内持续存在(例如函数或块),除非它们被堆分配或复制到别处。

从风格的角度来看,您真正想要做的是将所有Person问题都放到课堂上。如果"Bob"是默认名称,请创建一个构造函数方法,该方法指定:

Person() : name_("Bob") { };

这可以避免get_person()混淆。

答案 4 :(得分:0)

在你的代码中,人的名字就是bob。

方法签名通常接受引用,但有时您希望通过副本传递。

这可能是方法签名的有用参考。 http://www.cplusplus.com/articles/z6vU7k9E/