16.12编写你自己版本的Blob和BlobPtr模板,包含书中未定义的多个const成员。

Blob.h(注意,成员函数的声明和定义要放在一个头文件中)

/*记住,模板的头文件中通常既包括声明也包括定义。函数模板和类模板成员函数的定义通常放在头文件中,不能分开放。。。。谨记*/
#ifndef BLOB_H
#define BLOB_H
#include<iostream>
#include<vector>
#include<string>
#include<memory>
#include<initializer_list>
using namespace std;
template <typename> class BlobPtr;
template <typename> class Blob;
template <typename T>
bool operator==(const Blob<T>&,const Blob<T>&);
template <typename T>
class Blob
{
friend class BlobPtr<T>;
friend bool operator==<T>
(const Blob<T>&,const Blob<T>&);
public:
typedef T value_type;
typedef typename vector<T>::size_type size_type;
Blob();
Blob(initializer_list<T> il);
BlobPtr<T> begin() { return *this;}
BlobPtr<T> end() { auto ret=BlobPtr<T>(*this,this->size()); return ret;}
size_type size() const { return data->size();}
bool empty() const { return data->empty();}
void push_back(const T &t) { data->push_back(t);}
void push_back(T &&t) { data->push_back(std::move(t));}
void pop_back();
T& front();
T& back();
const T& front() const;
const T& back() const;
T& operator[](size_type i);
const T& operator[](size_type i) const;
private:
shared_ptr<vector<T>> data;
void check(size_type i,const string &msg) const;
};
template <typename T>
Blob<T>::Blob():
data(std::make_shared<std::vector<T>>()) { } template<typename T>
Blob<T>::Blob(initializer_list<T> il):data(make_shared<vector<T>>(il)) {} template<typename T>
void Blob<T>::check(size_type i,const string &msg) const
{
if(i>=data->size())
throw out_of_range(msg);
} template<typename T>
void Blob<T>::pop_back()
{
check(,"pop_back");
data->pop_back();
} template <typename T>
T& Blob<T>::front()
{
check(,"front");
return data->front();
} template<typename T>
T& Blob<T>::back()
{
check(,"back");
return data->back();
} template<typename T>
const T& Blob<T>::front() const
{
check(,"front");
return data->front();
} template<typename T>
const T& Blob<T>::back() const
{
check(,"back");
return data->back();
}
template<typename T>
T& Blob<T>::operator[](size_type i)
{
check(i,"out_of_range");
return (*data)[i];
} template<typename T>
const T& Blob<T>::operator[](size_type i) const
{
check(i,"out_of_range");
return (*data)[i];
}
template <typename T>
bool operator==(const Blob<T> &lhs,const Blob<T> &rhs)
{
if(rhs.size()!=lhs.size())
return false;
for(size_t i=;i!=lhs.size();+i)
if(lhs[i]!=rhs[i])
return false;
return true;
} template <typename T>
ostream operator<<(ostream &os,const Blob<T> &a)
{
os<<"<";
for(size_t i=;i!=a.size();++i)
os<<a[i]<<" ";
os<<">";
return os;
}
template <typename T>
bool operator==(const BlobPtr<T>&,const BlobPtr<T>&);
template <typename T> class BlobPtr
{
friend bool operator==<T>
(const BlobPtr<T>&,const BlobPtr<T>&);
public:
BlobPtr():curr(){}
BlobPtr(Blob<T> &a,size_t sz=):wptr(a.data),curr(sz){}
T& operator*() const
{
auto p=check(curr,"dereference past end");
return (*p)[curr];
}
BlobPtr& operator++();
BlobPtr& operator--();
BlobPtr& operator++(int);
BlobPtr& operator--(int);
private:
shared_ptr<vector<T>> check(size_t,const string &) const;
weak_ptr<vector<T>> wptr;
size_t curr;
};
template <typename T>
shared_ptr<vector<T>> BlobPtr<T>::check(size_t i,const string &msg) const
{
auto ret=wptr.lock();
if(!ret)
throw runtime_error("unbind BlobPtr");
if(i>=ret->size())
throw out_of_range(msg);
return ret;
} template <typename T>
BlobPtr<T>& BlobPtr<T>::operator++()
{
check(curr,"++");
++curr;
return *this;
}
template <typename T>
BlobPtr<T>& BlobPtr<T>::operator--()
{
--curr;
check(curr,"--");
return *this;
}
template <typename T>
BlobPtr<T>& BlobPtr<T>::operator++(int)
{
auto ret=*this;
++*this;
return ret;
} template <typename T>
BlobPtr<T>& BlobPtr<T>::operator--(int)
{
auto ret=*this;
--*this;
return ret;
} template <typename T>
bool operator==(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{
return (lhs.wptr.lock().get()==rhs.wptr.lock().get())&&lhs.curr==rhs.curr;
} template <typename T>
bool operator!=(const BlobPtr<T> &lhs,const BlobPtr<T> &rhs)
{
return !(rhs==lhs);
} #endif // BLOB_H

main.cpp

#include "Blob.h"

int main()
{
Blob<string> b1; // empty Blob
cout << b1.size() << endl;
{ // new scope
Blob<string> b2 = {"a", "an", "the"};
b1 = b2; // b1 and b2 share the same elements
b2.push_back("about");
cout << b1.size() << " " << b2.size() << endl;
} // b2 is destroyed, but the elements it points to must not be destroyed
cout << b1.size() << endl;
for(auto p = b1.begin(); p != b1.end(); ++p)
cout << *p << endl; return ;
}

16.14 编写Screen类模板,用非类型参数定义Screen的高和宽。

16.15为你的Screen模板实现输入和输出运算符。Screen类需要哪些友元来令输入和输出运算符正确工作。

#include<iostream>
#include <string>
using namespace std;
//模板非类型参数,友元一定要前置声明
template <unsigned H,unsigned W>
class Screen;
template <unsigned H,unsigned W>
ostream& operator<<(ostream &os,const Screen<H,W> &s);
template <unsigned H,unsigned W>
istream& operator>>(istream &is,Screen<H,W> &s);
template <unsigned H,unsigned W>
class Screen
{
friend ostream& operator<< <H,W> (ostream &os,const Screen<H,W> &s);
friend istream& operator>> <H,W> (istream &is,Screen<H,W> &s);
public:
typedef string::size_type pos;
Screen()=default;
Screen(pos ht,pos wd,char c):height(ht),width(wd),contents(ht*wd,c){}
char get() const
{
return contents[cursor];
}
inline char get(pos ht,pos wd) const;
Screen &move(pos r,pos c);
private:
pos cursor=;
pos height=H;
pos width=W;
string contents;
}; template<unsigned H,unsigned W>
char Screen<H,W>::get(pos ht,pos wd) const
{
pos row=ht*width;
return contents[row+wd];
} template <unsigned H,unsigned W>
Screen<H,W>& Screen<H,W>::move(pos r,pos c)
{
pos row=r*width;
cursor=row+c;
return *this;
}
template <unsigned H,unsigned W>
ostream& operator<<(ostream &os,const Screen<H,W> &s)
{
os<<s.cursor<<" "<<s.height<<" "<<s.width<<" "<<s.contents[s.cursor]<<endl;
return os;
}
template <unsigned H,unsigned W>
istream& operator>>(istream &is,Screen<H,W> &s)
{
is>>s.cursor>>s.height>>s.width>>s.contents;
return is;
}
int main()
{}

16.16

模板类之间的友元关系实现Blob和BlobPtr的更多相关文章

  1. Hibernate中的Entity类之间的继承关系之一MappedSuperclass

    在hibernate中,Entity类可以继承Entity类或非Entity类.但是,关系数据库表之间不存在继承的关系.那么在Entity类之间的继承关系,在数据库表中如何表示呢? Hibernate ...

  2. 06 (OC)* iOS中UI类之间的继承关系

    iOS中UI类之间的继承关系 此图可以更好的让你去理解iOS中一些底层的关系.你能够了解以及理解UI类之间的继承关系,你会更加明白苹果有关于底层的东西,更有助于你的项目开发由它们的底层关系,就能更加容 ...

  3. JAVA类与类之间的全部关系简述+代码详解

    本文转自: https://blog.csdn.net/wq6ylg08/article/details/81092056类和类之间关系包括了 is a,has a, use a三种关系(1)is a ...

  4. Java类与类之间的继承关系

    Java父类与子类继承关系,调用的各种关系 示例一(子类调用父类函数): // 定义一类 A public class A { // 此方法打印一句话 public void a() { System ...

  5. Java学习笔记——I/O流常用类之间的继承关系及构造方法

    朝辞白帝彩云间,千里江陵一日还. 两岸猿声啼不住,轻舟已过万重山. ——早发白帝城 总结一下有哪些I/O流: 输入流方法主要是read()和close(),输出流方法主要是write().flush( ...

  6. VS2015 查看类之间的继承关系

    ---恢复内容开始--- 1. 右击项目名称,单击"查看"菜单下的"查看类图"菜单: 2.生成的类图如下:

  7. python_面向对象——类之间的依赖关系

    class Dog: def __init__(self,name,age,master): self.name = name self.age = age self.master = master ...

  8. 齐博X1模板页面之间的继承关系

    本节说明下模板页面间的继承 我们在前面建立了一个公共布局模板,并且利用{block name=xxx}...{/block}分割了三个部分区块 本节我们来看下模板之前的继承如何实现,首先我们建立一个i ...

  9. eclipse如何查看类之间的引用关系

    今天遇到这个问题:mark一点点: 在类名上单击右键.选择Reference->Workingspace快捷克债券Ctrl+Shift+G 版权声明:本文博客原创文章,博客,未经同意,不得转载.

随机推荐

  1. 保存项目文件“XXX.csprj”时出错。类没有注册。

    [出错提示]保存项目文件“XXX”时出错.类没有注册.正在查找具有CLSID的对象:{D9B3211D-E57F-4426-AAEF-30A806ADD397}. [解决办法] 需要安装:MSXML_ ...

  2. 大数据量查询优化——数据库设计、SQL语句、JAVA编码

    数据库设计方面: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将 ...

  3. Z-Stack 软件架构分析

    转自Z-Stack 软件架构分析 Z-Stack的main函数在Zmain.c中,总体上来说,它一共做了两件工作,一个是系统初始化,即有启动代码来初始化硬件系统和软件架构需要的各个模块,另一个作用就是 ...

  4. phpStorm 快捷键收集以及配色方案

    仅收集我在开发过程中觉得对我个人很有帮助的 ctrl + e ;查看最近打开的工程文件 ctrl+shift+n比如要跳转到templates/default/index.html基本上输入te/de ...

  5. 你晓得吗?大多数企业根本没有做到 DevOps!

    作为当代 IT 企业提升效率的葵花宝典,DevOps 对 IT 企业效率的提升有目共睹 ,一时之间各大企业纷纷用提升效率的 DevOps 开发.协作.管理工具武装自己. 对比 2014 年上半年,CS ...

  6. 如何使用 HTTP 响应头字段来提高 Web 安全性?

    在 Web 服务器做出响应时,为了提高安全性,在 HTTP 响应头中可以使用的各种响应头字段. X-Frame-Options 该响应头中用于控制是否在浏览器中显示 frame 或 iframe 中指 ...

  7. 【Xamarin挖墙脚系列:应用的性能调优】

    原文:[Xamarin挖墙脚系列:应用的性能调优] 官方提供的工具:网盘地址:http://pan.baidu.com/s/1pKgrsrp 官方下载地址:https://download.xamar ...

  8. oracle的sqlnet.ora , tnsnames.ora , Listener.ora 文件的作用(转)

    oracle网络配置三个配置文件 listener.ora.sqlnet.ora.tnsnames.ora ,都是放在$ORACLE_HOME/network/admin目录下.1. sqlnet.o ...

  9. 子查询解嵌套not in 无法展开改写

    SQL> explain plan for select * from OPS$CZTEST1.SAVJ_ATOMJOURBAK where ((list_flag = '1' and prt_ ...

  10. ELK之topbeat部署

    topbeat定期收集系统信息如每个进程信息.负载.内存.磁盘等等,然后将数据发送到elasticsearch进行索引,最后通过kibana进行展示. 下面是具体的安装及配置步骤: 1.安装topbe ...