引入
在想显示数组当中所有元素时,我们往往会使用下面的for循环语句来遍历数组
cpp
#include <iostream>
#include <vector>
int main()
{
std::vector<int> v({ 1, 2, 3 });
for (int i = 0; i < v.size(); i++)
{
std::cout << v[i] << " " << std::endl;
}
return 0;
}
下面我们来对比一下,下面这一段遍历代码
cpp
#include <iostream>
#include <map>
int main()
{
std::map<int, int> mp;
mp[0] = 1;
mp[1] = 2;
mp[2] = 3;
for(std::map<int, int>::iterator iter = mp.begin(); iter != mp.end(); iter ++)
{
std::cout << "key is " << iter->first << " " << "value is " << iter->second << std::endl;
}
return 0;
}
二者在功能上实际上是一样的,都是对数据进行遍历输出。
在第一段代码当中,变量i
的作用是为了在自增之后,用做访问下一个元素的下标。
在第二段代码当中,变量*iter
*也是在自增之后,用来访问mp
的下一个元素,我们可以发现, 实际上在第二段代码当中,iterator
是对i
的一个抽象化、通用化的表达,这就是我们要学习的iterator
模式。
iterator
模式主要作用是对数据集合按照顺序进行遍历,在遍历的同时还要保证内部信息的封装性,只提供遍历接口。
iterator
模式常用于stl
容器当中,比如map
,list
等
UML类图
![](https://i-blog.csdnimg.cn/direct/45f29060d53e45a7b3bb848134ad6e07.png)
具体代码
book.h
cpp
#ifndef __BOOK_H__
#define __BOOK_H__
#include <iostream>
#include <string>
class Book
{
public:
Book(std::string name)
:m_nameStr(name)
{
std::cout << "value";
};
~Book() = default;
Book(const Book &other) = default;
Book& operator=(const Book &other) = default;
Book& operator=(Book &&other) = delete;
std::string getName() const
{
return m_nameStr;
};
protected:
private:
std::string m_nameStr;
};
#endif //__BOOK_H__
bookshelf.h
cpp
#ifndef __BOOKSHELF_H__
#define __BOOKSHELF_H__
#include <vector>
#include "book.h"
class BookShelf
{
public:
BookShelf() = default;
~BookShelf() = default;
BookShelf(const BookShelf &other) = default;
BookShelf& operator=(const BookShelf &other) = default;
BookShelf(BookShelf &&other) = delete;
BookShelf& operator=(BookShelf &&other) = delete;
//实现iterator
class iterator
{
public:
iterator(Book* tmp = nullptr) :iteratorPtr(tmp) {};
iterator& operator++()
{
iteratorPtr++;
return *this;
};
bool operator==(const iterator& other) const
{
return this->iteratorPtr == other.iteratorPtr;
}
bool operator!=(const iterator& other) const
{
return !(*this == other);
}
Book& operator*()
{
return *iteratorPtr;
}
private:
Book* iteratorPtr = nullptr;
};
//提供遍历起点
iterator begin();
//提供遍历终点
iterator end();
//添加书籍
void addBook(const Book& tmpBook);
protected:
private:
std::vector<Book> m_bookList;
};
#endif //__BOOKSHELF_H__
bookshelf.cpp
cpp
#include "bookshelf.h"
BookShelf::iterator BookShelf::begin()
{
return iterator(&m_bookList[0]);
}
BookShelf::iterator BookShelf::end()
{
return iterator(&(m_bookList.back()));
}
void BookShelf::addBook(const Book& tmpBook)
{
m_bookList.emplace_back(tmpBook);
}
main.cpp
cpp
#include "book.h"
#include "bookshelf.h"
int main()
{
Book book1("第一本书");
Book book2("第二本书");
Book book3("第三本书");
BookShelf woodBookShelf;
woodBookShelf.addBook(book1);
woodBookShelf.addBook(book2);
woodBookShelf.addBook(book3);
//得不到vector最后一个元素的后一个地址,所以只会输出
//第一本书、第二本书
for(BookShelf::iterator iter = woodBookShelf.begin(); iter != woodBookShelf.end(); ++iter)
{
std::cout << (*iter).getName() << std::endl;
}
system("pause");
return 0;
}
面向对象
- 设计模式的作用就是帮助我们编写可复用的类,当一个组件发生改变时,不需要对其他组件进行修改或是只进行很小的修改就可以应付
- 不要只用具体的类来编程,要优先使用抽象类和接口编程。
参考资料:图解设计模式