方法中的变量范围及其在C ++中的持久性

时间:2010-05-14 20:19:22

标签: c++ arrays vector scope

考虑以下公共方法,它将整数变量添加到C ++中的一个int(私有成员)向量中。

KoolMethod()
{
  int x;
  x = 10;
  KoolList.Add(x);
}
Vector<int>KoolList;

但这是向量的有效补充???在调用方法时,它会创建一个局部变量。此局部变量的范围在执行控制离开方法的那一刻结束。并且由于此局部变量在堆栈上分配(在方法调用上),因此KoolList的任何成员都指向解除分配堆栈中的无效内存位置,该位置可能包含也可能不包含x的预期值。这是对上述机制的准确描述吗?

每次需要将值添加到向量时,是否需要使用“new”运算符在堆存储中创建int,如下所述????:

KoolMethod()
{
  int *x = new int();
  *x = 10;
  KoolList.Add(x);
}
 Vector<int*>KoolList;   

4 个答案:

答案 0 :(得分:2)

  

但这是向量的有效补充吗?

是的,(标准库)矢量存储副本。

  

是否需要使用“new”运算符

在堆存储中创建int

如果您不希望复制对象或使用多态对象(请参阅object slicing),您可以使用指针。在这种情况下,您应该最好避免手动处理释放并使用包装器(智能指针或指针容器)来获得异常安全性。

答案 1 :(得分:2)

Vector<int>(至少如果它是std::vector)按值存储元素,因此对add()的调用会创建参数对象的副本并将该副本存储到数组中。因此,对于原始对象发生什么并不重要,只要向量本身(除非明确删除或覆盖),向量中的副本就是活着的。

如果您

Vector<X*>可能更合适
  • 希望使用多态X个对象,
  • 不想复制X的对象,例如因为这是昂贵的或不允许的,
  • 希望在不同方之间共享相同的对象

当然,这些都不适用于int,仅适用于真实物体。但是,最好将智能指针存储在向量中而不是原始指针,例如, vector<auto_ptr<X> > vector<shared_ptr<X> >。这些会自动管理对象的处理。

答案 2 :(得分:0)

如果你创建一个int的向量,它将不是一个指针向量。整数按值存储,不涉及指针,因此您不会遇到无效内存地址的任何问题。

以下是导致此类问题的代码示例:

std::vector<int *> my_list;

void a_method() {
    int value = 2; // allocated on the stack
    my_list.push_back(&value); // pushes a pointer to the stack... not good
}

答案 3 :(得分:0)

想一想:添加到标准向量会创建添加对象的副本。

在第一个代码片段中,您使用了int的向量,因此您将添加local int的副本,一切都很好。

在第二个代码片段中,您使用指向int的指针向量,因此您将添加指针的副本(此指针指向的对象的副本)。由于指针指向的对象在离开方法后仍然有效(它使用new运算符进行初始化并且不会在任何地方删除)一切都会很好。