引用的C++变量作用域
C++ variable scope for references
我很长时间以来第一次写C++,记不清了。我目前最纠结的是作用域(以及何时使用指针与引用作为输入参数(。具体来说,如果我在堆栈上创建了一些东西,它会在那里停留多久?
如果我有一个简单的类,比如:
class Person {
const std::string name_;
public:
Person(const std::string& name) : name_(name) {}
const std::string& get_name() { return name_; }
};
然后我有一个简单的人员生成器方法和主要:
Person* get_person() {
std::string name = "Bob";
return new Person(name);
}
int main (int argc, char **argv) {
Person* person = get_person();
// Is person's name Bob here? Or did Bob go out of scope?
delete person;
}
在我删除这个人之前,这个人的名字已经超出范围了吗?
我知道我可以创建一个新的std::字符串并将其传递给Person,但之后我还有一个变量要清理。在方法签名中接受指针或引用的标准是什么?
此外,欢迎参考有关此主题的教程。
让我们来分解一下:
Person* get_person() {
std::string name = "Bob"; // 1)
return new Person(name); // 2)
} // 3)
字符串名称已创建
这里在堆栈上创建字符串
name
。在堆上创建了一个新人
我们必须查看构造函数,看看发生了什么
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
是复制构造的到CCD_ 6中。因为人是在堆上创建的,所以name_
也生活在堆上。
c( 对name
的引用被销毁,因为它的作用域结束了。
- 块结束,因此
name
将超出范围。我们返回一个指向堆上的Person
的指针,因此Person
及其name_
不会被销毁
最重要的步骤是2.b)
。在这里,堆栈上的名称被复制构造到堆中。这是因为name_
不是一个引用,而是一个值,这使得它与传入的name
"独立"。
Tl;dr人名不会超出作用域,因为只有堆栈上的值才能超出作用域。在这种情况下,只有指向人员的指针位于堆栈上,而人员及其名称是在堆上创建的(通过new
(,不会超出范围。
您在这里没有任何问题。Person
的构造函数复制堆栈上的值。
只要堆栈相关,堆栈上分配的东西就会一直存在,并在堆栈弹出时立即销毁。
C++倾向于使用两种方法从堆栈中获取数据:在堆上进行分配,使其比当前堆栈范围持续更长时间;以及复制。
您的name
变量是一个堆栈分配的std::string
,但它被复制到您分配的C++对象,因为您通过引用而不是指针传递它。
在内部,字符串数据本身可能会在堆上分配,这就是这些容器通常的工作方式,但这并不是您真正关心的问题。
简而言之,堆栈对象在其作用域(例如函数或块(的持续时间内保持不变,除非它们被堆分配或复制到其他地方。
从风格的角度来看,您真正想做的是将所有Person
关注点合并到类中。如果"Bob"
是默认名称,则创建一个构造函数方法来分配:
Person() : name_("Bob") { };
这避免了get_person()
的混淆。
您的代码很好。
当您将对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.
在代码中,Person的名字应该是bob。
方法签名通常接受引用,但有时需要通过副本传递。
这可能是方法签名的有用参考。http://www.cplusplus.com/articles/z6vU7k9E/
- 在类函数中初始化外部作用域变量
- 不同作用域中的静态变量和全局变量
- 未在此作用域中声明的函数和变量 (C++)
- 如何在C++中访问作用域的变量输出?
- 不同块作用域中的 C++ 变量具有相同的地址
- "变量":函数中函数作用域不允许初始化的自动或寄存器变量'naked'
- Tictactoe 游戏变量未在作用域中声明
- C++If语句变量作用域
- 即使在离开作用域后,如何访问在堆上分配的变量C++?
- C++ 在方程中使用变量;错误:表达式必须具有整数或无作用域枚举类型及其他
- 局部变量的作用域是块或函数
- 当变量在多个函数作用域中使用时,我应该在类 private 中声明该变量吗?
- C++11 外部作用域变量声明为 auto
- 是一个初始化为未确定值或未初始化的本地作用域变量
- 命名空间作用域变量的c++初始化
- c++双删除文件作用域变量,链接问题
- 线程局部全局作用域变量
- 嵌套while循环中的作用域变量
- 如何从函数内部修改作用域变量
- c++中不一致的文件作用域变量行为