辨析std::vector::erase和std::remove (未完待续)

std::vector::erase

#include
详见: http://www.cplusplus.com/reference/vector/vector/erase/

iterator erase (const_iterator position);
iterator erase (const_iterator first, const_iterator last);
Erase elements
Removes from the vector either a single element (position) or a range of elements ([first,last)).
Return value
An iterator pointing to the new location of the element that followed the last element erased by the function call. This is the container end if the operation erased the last element in the sequence.
Example
// erasing from vector
#include 
#include 

int main ()
{
  std::vector myvector;

  // set some values (from 1 to 10)
  for (int i=1; i<=10; i++) myvector.push_back(i);

  // erase the 6th element
  myvector.erase (myvector.begin()+5);

  // erase the first 3 elements:
  myvector.erase (myvector.begin(),myvector.begin()+3);

  std::cout << "myvector contains:";
  for (unsigned i=0; i

Output

myvector contains: 4 5 7 8 9 10
erase的作用是删除迭代器position对应的元素并返回对应下一个元素的迭代器.
我看网上有这样的erase内部实现, 就想研究下erase内部到底干了什么.
iterator erase(iterator position)
{
  if(position + 1 !=end())
  {
     copy(position + 1,finish,position);
  }
  finish--;
  destroy(finish);
  return position;
}

std::copy

#include
template 
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result);

Copy range of elements
Copies the elements in the range [first,last) into the range beginning at result.
The function returns an iterator to the end of the destination range (which points to the element following the last element copied).
The ranges shall not overlap in such a way that result points to an element in the range [first,last). For such cases, see copy_backward.
The behavior of this function template is equivalent to:

template
  OutputIterator copy (InputIterator first, InputIterator last, OutputIterator result)
{
  while (first!=last) {
    *result = *first;
    ++result; ++first;
  }
  return result;
}
erase中copy的作用就是将position+1到finish之间的数据移动到以position开始的位置, 也就是前移一位.
这里有些地方不明白:
1. finish是什么?
2. 为何前移之后要destroy(finish)? 难道前移自动就将position元素移动到finish的位置了吗?

std::allocator::destroy

#include
template 
  void destroy (U* p);
Destroy an object
Destroys in-place the object pointed by p.
Notice that this does not deallocate the storage for the element (see member deallocate to release storage space).
The function uses U's destructor, as if the following code was used:
p->~U();
这里说没有deallocate元素的存储空间, 但是调用了析构函数? 我自己写了一段代码希望研究下erase:
#include 
#include 
#include 
using namespace std;

class pig{
private:
	int num;
public:
	pig(int n) : num(n){}
	~pig(){
		cout << "Pig " << num << " died!" << endl;
		num = 0;
	}
	int grunt(){ return num; }
	bool operator==(const pig& p){ return this->num == p.num; }
};
// I have to name differently the following two functions to prevent error from the 'find' function.
void gruntPigPt(pig *p){ cout << "Pig: " << p->grunt() << endl; }
void gruntPig(pig p){ cout << "Pig: " << p.grunt() << endl; }

void test1(){
	cout << "------------ Round One : Pig Pointers ------------" << endl;
	vector v;
	pig *second = NULL;
	for(int i = 1; i <= 5; ++i){
		pig *p = new pig(i);
		if(i == 2) second = p;
		v.push_back(p);
	}
	for_each(v.begin(), v.end(), gruntPigPt);
	auto it = find(v.begin(), v.end(), second); // To support 'auto', C++ 11 is needed.
	cout << "Found you! Pig: " << (*it)->grunt() << endl;
	it = v.erase(it);
	cout << "You are the next! Pig: " << (*it)->grunt() << endl;
	cout << "Here is Pig:" << second->grunt() << endl;
	delete second;
	for(int i = v.size() - 1; i >= 0; --i){
		pig *p = v.back(); v.pop_back();
		delete p;
	}
}

void test2(){
	cout << "------------ Round Two : Pigs ------------" << endl;
	vector v;
	for(int i = 1; i <= 5; ++i){
		pig p(i);
		v.push_back(p);
	}
	for_each(v.begin(), v.end(), gruntPig);
	auto it = find(v.begin(), v.end(), 3); // To support 'auto', C++ 11 is needed.
	cout << "Found you! Pig: " << it->grunt() << endl;
	it = v.erase(it);
	cout << "You are the next! Pig: " << it->grunt() << endl;
}

int main(){
	test1();
	test2();
	return 0;
}
Output:
------------ Round One : Pig Pointers ------------
Pig: 1
Pig: 2
Pig: 3
Pig: 4
Pig: 5
Found you! Pig: 2
You are the next! Pig: 3
Here is Pig:2
Pig 2 died!
Pig 5 died!
Pig 4 died!
Pig 3 died!
Pig 1 died!
------------ Round Two : Pigs ------------
Pig 1 died!
Pig 1 died!
Pig 2 died!
Pig 1 died!
Pig 2 died!
Pig 3 died!
Pig 4 died!
Pig 1 died!
Pig 2 died!
Pig 3 died!
Pig 4 died!
Pig 5 died!
Pig: 1
Pig 1 died!
Pig: 2
Pig 2 died!
Pig: 3
Pig 3 died!
Pig: 4
Pig 4 died!
Pig: 5
Pig 5 died!
Pig 3 died!
Pig 3 died!
Pig 3 died!
Found you! Pig: 3
Pig 5 died!
You are the next! Pig: 4
Pig 1 died!
Pig 2 died!
Pig 4 died!
Pig 5 died!
Round One不难理解, 它说明erase的时候并没有调用析构函数, 注意这是因为我在Round One中向vector中存储的是 指针(Pointer), 而不是 对象(Object), 因此没有调用指针的析构函数.
参考:  http://www.cplusplus.com/forum/general/63770/

Round Two就复杂了...未完待续.




你可能感兴趣的:(STL,C++)