More Exceptional C++ 读书笔记
Item 1 Switching Streams
(1): 多考虑易读性,避免编写过渡简洁但是不易懂,不易维护的代码;
记个相当简洁的流切换代码:
(argc > 2 ? ofstream(argv[2], ios::out|ios::binary) : cout ) << (argc > 1 ? ifstream(argv[1], ios::in|ios::binary) : cin).rdbuf();
(2): 设计函数时
a: 优先考虑可扩展性,但对于一个简单问题的处理不应当采用过渡设计和过于专一的发放,要权衡这两者;
b: 多考虑封装,将问题分离开;只要可能,就应当让一段代码只拥有一个功能;
Item 2Predicates, Part 1: What remove() Removes;
(1): remove()删除在[first,last)范围内的所有value 实例remove()以及remove_if()并不真正地
把匹配到的元素从容器中清除即容器的大小保留不变而是每个不匹配的元素依次被赋
值给从first 开始的下一个空闲位置上返问的ForwardIterator 标记了新的元素范围的下一个
位置例如考虑序列{0,1,0,2,0,3,0,4} 假设我们希望删除所有的0 则结果序列是
{1,2,3,4,0,3,0,4} 1 被拷贝到第一个位置上2 被拷贝到第二个位置上3 被拷贝到第三个位
置上4 被拷贝到第四个位置上返回的ForwardIterator 指向第五个位置上的0 典型的做法
是该iterator 接着被传递给erase() 以便删除无效的元素内置数组不适合于使用remove()
和remove_if()算法因为它们不能很容易地被改变大小由于这个原因对于数组而言
remove_copy()和remove_copy_if()是更受欢迎的算法.
(2): 一个remove_nth的正确实现:
template<FwdIter>
FwdIter remove_nth(FwdIter first, FwdIter last, size_t n)
{
assert(distance(first, last) >= n);
advance(first, n);
if(first != last)
{
FwdIter dest = first;
return copy(++first, last, dest);
}
return last;
}
(3): 多考虑泛型算法 + 断言的形式,而不是重新实现一个泛型算法;
(4): 所谓断言是一个函数指针或者函数对象, 返回一个bool,泛型算法依据返回值执行相应操作;
(5): stateful 断言;不依赖泛型算法传递对象到operator(),而是根据调用次数独立的自动更新函stateful断言内的数据;
(6): stateful断言对泛型算法的要求:
a: 泛型算法必须用一个恒定的函数对象,而不能用其拷贝来作运算;
b: 泛型算法必须把函数对象按照已知的顺序提交给每一个容器中的元素;
c: 一个安全的stateful断言:
template<class T>
class CountedPtr
{
private:
class Impl
{
public:
Impl(T* pp) : p(pp), refs(1) {}
~Impl() { delete p; }
T* p;
size_t refs;
};
Impl *impl_;
public:
explicit CountedPtr(T *p) : impl_(new Impl(p) ) {}
~CountedPtr() { Decrement(); }
CountedPtr(const CountedPtr &other) : impl_(other.impl_) { Increment(); }
CountedPtr& operator=(const CountedPtr& othher)
{
if(impl_ != other.impl_)
{
Decrement();
impl_ = other.impl_;
Increment();
}
return *this;
}
T* operator->() const { return impl_->p;}
T& operator*() const { return *(impl_->p); }
private:
void Dcrement()
{
if(--(impl_->refs) == 0)
delete impl_;
}
void Increment() { ++(impl_->refs); }
};
class FlagNthImpl
{
public:
FlagNthImpl(size_t nn) : i(0), n(nn) {}
size_t i;
const size_t n;
};
class FlagNth
{