随笔-1  评论-0  文章-0  trackbacks-0
一个很简单的例子:
#include <iostream>
#include 
<vector>
using namespace std;

int main()
{
    vector
<int> v;
    
int* second;

    
for (int i = 0; i < 10; i++) {
        v.push_back(i);
    }
    second 
= &v[1];
    cout 
<< *second << endl;

    
for (int i = 0; i < 100; i++) {
        v.push_back(i);
    }
    cout 
<< *second << endl;

    
return 0;
}
输出结果可想而知。前者为1,后者无效。


STL中说过,当vector在添加新元素时,如果空间已经不足以保存新元素,则开辟一块新的空间,并把之前内容复制到新的空间中去。所以second所指向的元素内存地址已经改变,second变成了一个无效指针。
如果用引用:
#include <iostream>
#include 
<vector>
using namespace std;


int main()
{
    vector
<int> v;
    

    
for (int i = 0; i < 10; i++) {
        v.push_back(i);
    }
    
int& second = v[1];
    cout 
<< second << endl;

    
for (int i = 0; i < 100; i++) {
        v.push_back(i);
    }
    cout 
<< second << endl;

    
return 0;
}
效果相同,事实上很多编译器的引用就是用指针实现的。


这种应用其实非常之多,比如在表达一个Graph:
1 #include <iostream> 2 #include <vector> 3 using namespace std; 4 5 6 class vertex; 7 class edge; 8 class graph; 9 10 class vertex 11 { 12 public: 13 double _x, _y, _z; 14 }; 15 16 class edge 17 { 18 //edge中保存两个对应顶点的地址 19 public: 20 vertex* v0; 21 vertex* v1; 22 }; 23 24 class graph 25 { 26 //一些初始化函数 27 graph(); 28 graph(vertex v[], int nbv, edge e[], int nbe); 29 30 //假设某个函数会插入一组顶点 31 void insert_v(vertex v[], int nbv) 32 { 33 for (int i = 0; i < nbv; i++) { 34 _v_set.push_back(v[i]); 35 } 36 } 37 38 39 //假设用vector来保存edge & vertex 40 public: 41 vector<vertex> _v_set; 42 vector<edge> _e_set; 43 }; 44
当调用insert_v时,如果_v_set空间不足进行了拷贝, 则之前所有edge关联顶点的指针全部失效。这就是一场灾难。当调用insert_v时,如果_v_set空间不足进行了拷贝, 则之前所有edge关联顶点的指针全部失效。这就是一场灾难。


一种更好的方式来保存索引号,即:
class edge
{
 
//edge中保存两个对应顶点的索引
 public:
     
int _v0_handle;
     
int _v1_handle;
};



posted on 2010-06-17 17:22 tuoxieman 阅读(776) 评论(0)  编辑 收藏 引用 所属分类: C++

只有注册用户登录后才能发表评论。
网站导航:   博客园   博客园最新博文   博问   管理