我知道一个对象超出范围的情况。例如,假设我们从main()调用了函数foo()。
int foo()
{
someobject obj;
//do something with this object
return -1;
}
现在我知道,因为这个对象是在堆栈上声明的,所以当foo()结束时,这个对象将从堆栈中删除。 有人可以解释 其他对象超出范围的情况吗? 另一件事, 为什么这个对象在堆栈上声明?
答案 0 :(得分:1)
void foo()
{
int obj1;
{
int obj2;
// obj1, obj2 can be used here
{
int obj1;
//in this scope obj1 is not the first obj1, it's the one declared in previous line
}
// obj1 in this will refer the first obj1
}
}
关于在函数内创建一些对象时默认的第二个问题,它将在堆栈上。它是首选的,因为我们不必处理分配的内存。它将自动从堆栈中删除。
我们可以使用new在堆上创建内存但是在这种情况下我们必须确保一旦完成,我们已经删除了已分配的内存,或者确保转移了对象的所有权以便删除它。
检查以下情况。
void foo1()
{
int* i = new int(23);
// use i here ...
// .....
delete i; // once done delete the memory, it exception is thrown here i will not be deleted so make sure to use smart pointer(RAII)
}
void foo2()
{
unique_ptr<int> iPtr(new int(23));
// use iPTr here ...
// .....
// no need to delete allocated memory, unique_ptr will handle that
}
为避免不必要的内存管理,我们在堆栈上创建对象。同样在嵌入式域中,不建议使用动态内存分配,因为它不安全。
答案 1 :(得分:0)
这是在栈上声明的对象,因为一旦调用了这个返回的整数函数,就可以说它已经实现了它的目的。我会说你首先使用这个对象的方式有点奇怪。为什么不直接将对象的引用作为函数的输入参数传递。
int foo(object) {
}
对于其他对象可能超出范围的情况,仅取决于创建对象的线程或位置。
答案 2 :(得分:0)
C ++中有两个重要概念:
这两者相互作用但是截然不同。 (还有第三个概念,对象生命周期,,对于“普通”程序几乎与对象的存储持续时间相同;让我们暂时忽略它。)
我们来看看范围。
范围表示“名称在哪里可见且有效”。中心概念是名称。标准在3.3.1中说明
通常,每个特定的名称仅在某些可能的范围内有效 程序文本的不连续部分称为范围。 [由我强调。]
i
之类的名称可能超出范围。这意味着不能再使用它来引用特定对象。您给出的示例是正确的:当一个封闭的块(如函数体)被留下时。另一个例子是两个实体具有相同的名称,如全局i
和本地循环变量i
。全局i
的范围不包含循环(这是一个不同的i
)。但是全局i
对象的存储持续时间(以及生命周期)当然包括循环 - 它仍然是“那里”(例如,可以使用指针访问它)。
相比之下,存储持续时间不是正式的语法问题,而是实际的运行时间问题。中心概念是存储:适当命名的存储持续时间描述了持有对象的存储有效的时间。 (请参阅此处我们如何关注名称。)标准在3.7中说明:
存储持续时间是定义的对象的属性 包含存储的最小潜在生命周期 物体。存储持续时间由 用于创建对象的构造,并且是以下之一:
- 静态存储时间
- 线程存储持续时间
- 自动存储时间
- 动态存储时间
[我强调。]
最简单的“创建对象的构造”是简单地在函数内声明局部变量。这样创建的存储具有恰当命名的“自动”存储持续时间 - 实现在执行定义时创建对象(最新?),并在保留名称范围时为您销毁对象。对于自动变量,名称范围和存储持续时间之间的连接很强。
但请注意,也可以在块内声明外部变量或函数,因此具有外部实体的本地范围名称:
$ cat local-external.cpp && g++ -Wall -o local-external local-external.cpp && ./local-external
int main()
{
{
extern int i;
}
i=1;
}
local-external.cpp: In function ‘int main()’:
local-external.cpp:4:14: warning: unused variable ‘i’ [-Wunused-variable]
extern int i;
^
local-external.cpp:6:2: error: ‘i’ was not declared in this scope
i=1;
^
i
的范围与局部变量相同 - 从声明到封闭块的末尾 - 但是它的存储持续时间(如果存在对象)例如,在不同的文件中定义)将是静态的,因为它是一个外部变量,并且与程序一样长。如果将赋值移动到内部块以便代码编译,则链接器会抱怨它无法找到外部对象i
(应该在某处留出的存储空间)。
当然很少有这样的事情;这只是一次示威。 (声明本地函数可能最常做inadvertently。)