考虑以下公共方法,它将整数变量添加到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;
答案 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运算符进行初始化并且不会在任何地方删除)一切都会很好。