2014-10-06 88 views
0

关于如何在C++中安全地传递和使用向量的快速问题。在C++中通过指针和引用传递向量

我知道,在使用矢量时,你必须非常小心地址给他们和他们的元素,因为当你动态改变他们的大小时,他们可能会改变他们的地址(除非你使用预留等,但我想象着我不会知道我需要多少空间)。

现在我想通过一个现有的矢量(在其他地方创建)到一个函数来调整它并改变它的大小等,但我有点不清楚什么是安全的,因为我通常会实现所有这些与指针。最重要的是使用对矢量的引用,这只是为我的泥水。

例如采取以下两种职能和评论他们

void function1(std::vector<int>* vec){ 

    std::cout<<"the size of the vector is: "<<vec->size()<<std::endl; //presumably valid here 

    for (int i=0;i<10;i++){ 

     (*vec).pushback(i); //Is this safe? Or will this fail? 
     // Or: vec->pushback(i); Any difference? 
    } 

    std::cout<<"the size of the vector is: "<<vec->size()<<std::endl; //Is this line valid here?? 

} 

void function2(std::vector<int>& vec){ 

    std::cout<<"the size of the vector is: "<<vec.size()<<std::endl; //presumably valid here 

    for (int i=0;i<10;i++){ 

     vec.pushback(i); //Is this safe? Or will this fail? 

    } 

    std::cout<<"the size of the vector is: "<<vec.size()<<std::endl; //Is this line valid here?? 

} 

有两个功能之间的任何差别,无论是在功能方面和在安全性方面?或者换句话说,如果我只有一个指向矢量的指针/引用,并且需要调整它的大小,我该如何确定矢量实际上在内存中的位置,或者指向矢量的指针真的在哪里我操作它。谢谢。

+1

这两个都是有效的。你必须小心处理的只是元素内**的地址**向量和迭代器。因此,如果你在内部执行了'int * foo =&vec [0]',然后'push_back'ed元素,那么这个指针可能在之后无效。然而,无论矢量执行的操作如何,指向矢量的指针仍然有效。 – Xarn 2014-10-06 14:27:27

+0

一个向量管理它自己的内存,所有你必须担心的是你传入的*实例*。期望指针的函数对我来说意味着在使用它之前会检查* pointee *是否有效,另一方面参考将不会做这样的检查。除了检查,功能上他们是一样的。 – Nim 2014-10-06 14:28:06

+0

好的,辉煌的,谢谢。所以我基本上混淆了向量与数组?就像在一个数组中,指向它的指针可以被认为是指向第一个元素的指针,从中可以使用指针算术来访问它的其余部分。但是对于矢量而言,它是一个指向容器的指针,该容器是一些可能被该容器改变的连续内存的接口。 – user3353819 2014-10-06 14:31:47

回答

1

就功能而言,在您给予我们的非常有限的环境中,它们基本上是相同的。

在更普遍的看法,如果你想写通用代码,考虑到操作和运营商直接绑定到引用,而不是指针

a = b + c; 

编译需要

A operator+(const B&, const C&); 

A* operator+(const B*, const C*); 

是一个不同的野兽。另外,一个采用引用和取值的表达式具有相同的语法,但采取指针的表达式需要指针提供相同的语义,但这会导致不同的表达式语法(*a + *ba+b),从而导致“较少通用代码“。如果你正在编写一个具有运行时多态性的类(以及脑中的lyskov替换),那么你很可能会对待动态分配的对象,因此,通过指针操纵它们可能更自然。

存在两个东西网格化的“灰色区域”,但是在基于运行时的OOP框架中,通用指针捕捉函数更频繁,而“基于值的泛型算法”中参考捕捉函数更频繁,其中静态预计会出现类型扣除,并且最有可能需要基于堆叠的分配。