读书人

关于vector赋值的有关问题

发布时间: 2012-12-18 12:43:41 作者: rapoo

关于vector赋值的问题
本帖最后由 zhuyf87 于 2012-12-07 16:26:27 编辑


void UploadCheckInTobacco::set_check_in_tobacco(std::vector<CheckInTobaccoDetail> & check_in_tobacco_vector)
{
check_in_tobacco_vector_.clear();
std::vector<CheckInTobaccoDetail>::iterator iterator;
for (iterator = check_in_tobacco_vector.begin(); iterator != check_in_tobacco_vector.end(); ++iterator)
check_in_tobacco_vector_.push_back(*iterator);
}


这个函数,将形参check_in_tobacco_vector容器中的所有元素,赋给class UploadCheckInTobacco的成员变量check_in_tobacco_vector_。赋值之前先清空check_in_tobacco_vector_。现在这样做,是不是效率比较低?假设上面的做法叫做(1),下面我想到另外两种做法,是否会提高效率?

(2)

void UploadCheckInTobacco::set_check_in_tobacco(std::vector<CheckInTobaccoDetail> & check_in_tobacco_vector)
{
check_in_tobacco_vector_.clear();
copy(check_in_tobacco_vector.begin(),
check_in_tobacco_vector.end(),
back_inserter(check_in_tobacco_vector_));
}


(3)

void UploadCheckInTobacco::set_check_in_tobacco(std::vector<CheckInTobaccoDetail> check_in_tobacco_vector)
{
check_in_tobacco_vector_.swap(check_in_tobacco_vector);
}

因为我不想改变实参vector(由于某种原因),所以参数这里没有使用引用型参数。但是check_in_tobacco_vector通常里面的数据比较多,不用引用型参数是否会降低程序性能?

希望得到大家帮助,给我提提建议,怎么做才最好。谢谢。-_-

[最优解释]
1和2的做法都是不推荐的,3完全交给拷贝构造函数去做了,多了一次构造和析构
实际上有一个更好的方法,就是用容器自带的assign来进行赋值

void UploadCheckInTobacco::set_check_in_tobacco(std::vector<CheckInTobaccoDetail> check_in_tobacco_vector) 
{
check_in_tobacco_vector_.assign(check_in_tobacco_vector.begin(), check_in_tobacco_vector.end());
}


挨个push_back也好,copy也好(back_inserter实际也只不过是push_back的包装),都可能会因为容量变大而出现多次内存分配,而容器自己提供的assign没有这个问题

就算是3的拷贝构造方式,实际上内部也是调用了赋值的过程,与assign的方法的区别在于,assign内部是先清空再插入,没有构造和析构,而拷贝构造是直接插入,需要构造和析构
[其他解释]
(3) 应该不会比 (1)(2) 慢,是否快得看具体实现。
[其他解释]
不想改变输入参数可以用常引用const &
为啥不直接用=号复制
[其他解释]
直接赋值啊

不知道你是否真正需要一份单独的复制.
否则保留个指针或引用就可以了啊.
肯定比一个一个复制要快的.
赋值的时候肯定知道有多少个元素.而你一个一个复制的时候会涉及内存的重新申请.

[其他解释]
可以使用就行了,常用(1)
[其他解释]
如果效率特别敏感,类成员可以用智能指针。接口定义成智能指针,从而避免额外的copy。

关于智能指针,TR1里面shared_ptr
VS2010中,shared_ptr,则#include <memory>
使用的时候 tr1::shared_ptr

boost(需要下载)的也可以用
#include <boost/smart_ptr.hpp>
使用的时候 boost::smart_ptr

或者你自己实现一个智能指针的类,通过引用计数管理内存。
[其他解释]
第二种会比较好。
[其他解释]
我总结了上面各楼的回复,写了如下的代码。至少这些函数都可以实现复制的功能。如果要测试性能,可以在如下代码的基础上添加测试代码。

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;

class foo
{


public:
vector<int> vec_;
void set_vec0(vector<int>& vec);
void set_vec1(vector<int>& vec);
void set_vec2(vector<int>& vec);
void set_vec3(vector<int> vec);
void set_vec4(vector<int>& vec);
void print();
};

void foo::set_vec0(vector<int>& vec)
{
vec_=vec;
print();
}

void foo::set_vec1(vector<int>& vec)
{
vec_.clear();
for (vector<int>::iterator it = vec.begin(); it != vec.end(); ++it)
{
vec_.push_back(*it);
}
print();
}

void foo::set_vec2(vector<int>& vec)
{
vec_.clear();
copy(vec.begin(), vec.end(), back_inserter(vec_));
print();
}

void foo::set_vec3(vector<int> vec)
{
vec_.swap(vec);
print();
}

void foo::set_vec4(vector<int>& vec)
{
vec_.assign(vec.begin(), vec.end());
print();
}

void foo::print()
{
int i=0;
for (vector<int>::iterator it = vec_.begin(); it != vec_.end(); ++it)
{
cout<<*it;
if((i+1)%5!=0)
{
cout<<'\t';
}
else
{
cout<<endl;
}
i++;
}
cout<<endl;
}

int main()
{
int a[7]={0,1,2,3,4,5,6};
vector<int> vec(a,a+7);

foo c;
c.set_vec0(vec);
c.set_vec1(vec);
c.set_vec2(vec);
c.set_vec3(vec);
c.set_vec4(vec);

return 0;
}


[其他解释]
引用:
不想改变输入参数可以用常引用const &
为啥不直接用=号复制


使用赋值操作符,与上面3种方法比,哪一种是比较推荐的方式呢?
以大家经验来看。
[其他解释]
打错了 boost::shared_ptr。。。擦。。
[其他解释]
谢谢大家,感觉9楼说的很好。-_-
[其他解释]
测试一下,就知道。

读书人网 >C++

热点推荐