草庐IT

<四>MyVector中加入迭代器功能

ericshi1985 2023-03-28 原文

我们之前有<C++模板编程模块>中的第<四>节 理解空间配置器allocator优化STL中的Vector
我将在此基础上加入迭代器功能代码


Iterator 为什么可以遍历所有的容器的方式都一样?
auto it =continer.beign();
for( ;it!=continer.end();++it){
    cout<<*it<<endl;
}

//我们在自己的容器里的 Iterator 的 ++运算 , *运算 由自己来实现,所有对外部使用者来看都是统一的.
//泛型算法能够给所有的容器都使用,也是基于容器对外提供了统一的遍历接口, 其参数接受的都是容器的迭代器


#include <iostream>
using namespace std;


class person {
public:
	//构造函数
	person(int _age=1,char * _pname=nullptr):
	age(_age)
	{
		if (_pname == nullptr) {
			pname = new char[1];
			pname[0] = '\0';
		}
		else {
			int size = strlen(_pname);
			pname = new char[size + 1];
			strcpy(pname, _pname);
		}
		cout << "创建student对象,地址=" << this << endl;
	}
	//拷贝构造函数
	person(const person & _person) {
		this->age = _person.age;
		int size = strlen(_person.pname);
		pname = new char[size + 1];
		strcpy(this->pname, _person.pname);

	}

	//赋值函数
	person & operator=(const person & _person) {
		if (this == &_person) { return *this; }
		delete[]pname;
		pname = nullptr;
		this->age = _person.age;
		int size = strlen(_person.pname);
		pname = new char[size + 1];
		strcpy(this->pname, _person.pname);
		return *this;
	}
	~person() {
		cout << "析构 person =" <<pname << " "<<age << endl;
		delete[]pname;
		pname = nullptr;		
	}

	
private:
	int age;
	char * pname;
	friend ostream & operator<<(ostream & out, const person & _value);
};

ostream & operator<<(ostream & out, const person & _value) {
	cout << _value.pname<<" == "<< _value.age << " "  << endl;
	return out;
}


template <typename T>
class Allocate4 {

public:
	
	//分配内存空间,不创建对象
	T * allocator(int size=4) {
		return (T *)malloc(sizeof(T)*size);
	}
	
	//在指定的内存空间地址,构建 T对象
	void constract(T * pAddress, const T & _val) {
		new (pAddress) T(_val);
	}

	//释放指定位置的内存空间
	void delAllocator(T * pAddress) {
		if (pAddress != nullptr) {
			free(pAddress);
			pAddress = nullptr;
		}
	}

	//析构指定内存位置
	void destory(T * pAddress) {
		pAddress->~T();//调用析构函数
	}

};


template<typename T,typename Allocate= Allocate4<T>>
//类模板
class MyVector4 {

public:

	MyVector4<T,Allocate>(int size = 4 , const Allocate _rallocator = Allocate4<T>)
	: _allocator(_rallocator)
	{
		pfirst = _allocator.allocator(size);
		last = pfirst;
		pend = pfirst + size;
		cout << "MyVector开辟内存地址=" << pfirst<<endl;
	}

	MyVector4<T, Allocate>(const MyVector4<T, Allocate> & _vector)
	{
		//1:根据原vector的空间大小申请新的内存空间
		pfirst = _allocator.allocator(_vector.size());
		last   = pfirst;
		pend   = pfirst + size;

		//2:将原vector空间中的有效对象赋值到新的vector中
		T * _pFlag = _vector.pfirst;
		while (_pFlag != _vector.last) {
			_allocator.constract(last, *_pFlag);
			_pFlag++;
			last++;
		}
	}

	MyVector4<T, Allocate> & operator=(const MyVector4<T, Allocate> & _vector)
	{
		if (this == &_vector) {
			return *this;
		}

		//1:析构现有vector中的有效对象
		T * _pFlag = pfirst;
		while (_pFlag !=last) {
			_allocator.destory(_pFlag);
			_pFlag++;
		}

		//2:释放现有的vector申请的堆内存空间
		_allocator.delAllocator(pfirst);
		pfirst = nullptr;
		pend = nullptr;
		last = nullptr;

		//3:根据_vector的内存空间大小,申请新的堆内存空间
		pfirst = _allocator.allocator(_vector.size());
		last = pfirst;
		pend = pfirst + _vector.size();
		
		//4:将_vector中有效的对象复制到现在新的堆空间中	
		T * _pFlag = _vector.pfirst;
		while (_pFlag != _vector.last) {
			_allocator.constract(last, *_pFlag);
			_pFlag++;
			last++;
		}
		
	}

	void pushBack(const T & _val)  {
		if (Full()) {
			Expend();
		}
		_allocator.constract(last, _val);	
		cout << "pushBack 原对象 地址=" << &_val  <<"放在内存位置 "<<last<< endl;
		this->last++;
	}

	void popBack()  {
		if (Empty()) { return ; }
		_allocator.destory(this->last-1);
		this->last--;
	}

	//内存空间扩展
	void Expend() {
		int newSize = 2*this->size();
		
		//1:申请新的内存空间
		T * tep_pfirst = _allocator.allocator(newSize);
		T * tep_last = tep_pfirst;
		T * tep_pend = tep_pfirst + newSize;

		//2:原当前vector中原有效的对象复制到新的堆空间上
		T * _pFlag = pfirst;
		while (_pFlag != last) {
			_allocator.constract(tep_last, *_pFlag);
			_pFlag++;
			tep_last++;
		}

		//3:析构原有对象
		_pFlag = pfirst;
		while (_pFlag != last) {
			_allocator.destory(_pFlag);
			_pFlag++;
		}

		//4:释放原有的vector申请的堆内存空间
		_allocator.delAllocator(pfirst);
		pfirst = nullptr;
		pend = nullptr;
		last = nullptr;

		//5:指针重新指向
		pfirst = tep_pfirst;
		last   = tep_last;
		pend   = tep_pend;

		cout << "MyVector空间2倍扩展,新的地址=" << pfirst << endl;
	}

	bool Empty() const {
		return this->pfirst == this->last;
	}
	
	bool Full() const {
		return this->pend == this->last;
	}
	int size() {
		return this->pend - this->pfirst;
	}

	void showVectorInfo() {
		T * tep = pfirst;
		while (tep < last)
		{
			cout << "打印Vector中有效对象地址=" << tep << endl;
			tep++;
		}
	}

	//定义属于自己的迭代器
	class Iterator {

	public:

		Iterator( T * _pAddress=nullptr):pAddress(_pAddress) {
		}

		const T & operator*() const {
			return *pAddress;
		}

		T & operator*() {
			return *pAddress;
		}
		//前置++
		void operator++() {
			this->pAddress++;
		}

		bool operator!=(const Iterator & src) const {
			return this->pAddress != src.pAddress;
		}

	private:
		T * pAddress;
	};

	Iterator begin() const {
		return Iterator(this->pfirst);
	}

	Iterator end() const {
		return Iterator(this->last);
	}

private:
	T * pfirst;//指向首元素地址
	T * pend;  // 指向容器最后位置的下一个地址
	T * last;  //指向最后一个有效元素的下一个位置
	Allocate _allocator;
};



void testV4() {

	MyVector4<person, Allocate4<person>> v5(4,Allocate4<person>());

	person p1(10,"zs1");
	v5.pushBack(p1);

	person p2(20, "zs2");
	v5.pushBack(p2);

	person p3(30, "zs3");
	v5.pushBack(p3);

	person p4(40, "zs4");
	v5.pushBack(p4);

	v5.showVectorInfo();

	cout << "-------" << endl;
	person p5(50, "zs5");
	v5.pushBack(p5);

	v5.showVectorInfo();

	v5.popBack();

	MyVector4<person, Allocate4<person>>::Iterator  it_begin = v5.begin();
	MyVector4<person, Allocate4<person>>::Iterator  it_end   = v5.end();

	cout << "---iterator begin----" << endl;
	
	for (; it_begin != it_end; ++it_begin) {
		cout << *it_begin << endl;
	}

	cout << "---iterator end----" << endl;

}


int main() {

	testV4();
	system("pause");
	return 0;

}//pendl

有关<四>MyVector中加入迭代器功能的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  3. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  4. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  5. ruby-on-rails - Cucumber 是否只是 rspec 的包装器以帮助将测试组织成功能? - 2

    只是想确保我理解了事情。据我目前收集到的信息,Cucumber只是一个“包装器”,或者是一种通过将事物分类为功能和步骤来组织测试的好方法,其中实际的单元测试处于步骤阶段。它允许您根据事物的工作方式组织您的测试。对吗? 最佳答案 有点。它是一种组织测试的方式,但不仅如此。它的行为就像最初的Rails集成测试一样,但更易于使用。这里最大的好处是您的session在整个Scenario中保持透明。关于Cucumber的另一件事是您(应该)从使用您的代码的浏览器或客户端的角度进行测试。如果您愿意,您可以使用步骤来构建对象和设置状态,但通常您

  6. ruby-on-rails - 没有参数的 `<<`(小于两倍)是什么意思? - 2

    我在一个我想在formtasticGem中覆盖的方法中找到了这个。该方法如下所示:defto_htmlinput_wrappingdohidden_field_html是什么意思?在第三行做什么?我知道它对数组有什么作用,但在这里我不知道。 最佳答案 你可以这样读:hidden_field_htmllabel_with_nested_checkbox是连接到hidden_​​field_html末尾的参数-为了“清晰”,他们将其分成两行 关于ruby-on-rails-没有参数的`

  7. ruby-on-rails - 找不到 gem railties (>= 0.a) (Gem::GemNotFoundException) - 2

    我已经看到了一些其他的问题,尝试了他们的建议,但没有一个对我有用。我已经使用Rails大约一年了,刚刚开始一个新的Rails项目,突然遇到了问题。我卸载并尝试重新安装所有Ruby和Rails。Ruby很好,但Rails不行。当我输入railss时,我得到了can'tfindgemrailties。我当前的Ruby版本是ruby2.2.2p95(2015-04-13修订版50295)[x86_64-darwin15],尽管我一直在尝试通过rbenv设置ruby​​2.3.0。如果我尝试rails-v查看我正在运行的版本,我会得到同样的错误。我使用的是MacOSXElCapitan版本10

  8. ruby-on-rails - 连接字符串时如何在 <%=%> block 内输出 html_safe? - 2

    考虑一下:现在这些情况:#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2#output:http://domain.com/?foo=1&bar=2我需要用其他字符串输出URL。我如何保证&符号不会被转义?由于我无法控制的原因,我无法发送&。求助!把我的头发拉到这里:\编辑:为了澄清,我实际上有一个像这样的数组:@images=[{:id=>"fooid",:url=>"http://

  9. Ruby -> 写入二维数组 - 2

    我正在处理http://prepwork.appacademy.io/mini-curriculum/array/中概述的数组问题我正在尝试创建函数my_transpose,它接受一个矩阵并返回其转置。我对写入二维数组感到很困惑!这是一个代码片段,突出了我的困惑。rows=[[0,1,2],[3,4,5],[6,7,8]]columns=Array.new(3,Array.new(3))putscolumns.to_s#Outputisa3x3arrayfilledwithnilcolumns[0][0]=0putscolumns.to_s#Outputis[[0,nil,nil],[

  10. ruby-on-rails - rails 功能测试 - 2

    在Rails自动生成的功能测试(test/functional/products_controller_test.rb)中,我看到以下代码:classProductsControllerTest我的问题是:方法调用products()在哪里/如何定义?products(:one)到底是什么意思?看代码,大概意思是“创建一个产品”,但是它是如何工作的呢?注意我是Ruby/Rails的新手,如果这些是微不足道的问题,我深表歉意。 最佳答案 如果您查看test/fixtures文件夹,您会看到一个products.yml文件。这是在您创建

随机推荐