pointer-like class
什么是
让一个类像 pointer 一样,对 * 和 -> 这两个符号重载了。
为什么要
在单独的指针基础上有更多的功能。比如 shard_ptr,比如迭代器。
具体例子
- shard_ptr
template<class T>
class shard_ptr {
public:
shard_ptr(T* p):px(p){}
T& operator*() const {
return *px;
}
T* operator->() const {
return px;
}
private:
T* px;
long* pn;
// ...
};
现在看这个很奇怪的例子:
class Foo {
public:
void fun1() {}
};
int main() {
shard_ptr<Foo>sp(new Foo);
sp->fun1();
return 0;
}
上面的 sp 是一个 shard_ptr。sp 首先调用了 operator->()
返回了原来的 Foo*。但是 -> 不是消耗了 -> 符号吗?为什么之后还有。原来 C++ 规定对于调用->
操作符后,->
操作符并不消耗掉,而是会继续作用下去。
- 迭代器
参考
- 侯捷《面向对象高级编程(下)》
function-like class
什么是
就是一个重载了 () 的类,让这个类的对象看起来能像一个函数一样。
为什么要
我感觉可以让代码更灵活,更短。
具体例子
我们首先看一个把 vector 中的所有数字加上 42 的例子。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int add42(const int& x) {
return x + 42;
}
int main() {
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2(v1.size());
transform(v1.begin(), v1.end(), v2.begin(), add42);
for(auto v : v2) {
cout << v << '\n';
}
return 0;
}
如果需求改了,需要加上 21 需要加上 100 就得需要多定义两个函数。但是使用 functor 就可以避免这样的冗余,像这样:
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
class add_x {
public:
add_x(const int& x):x(x){}
int operator() (const int& t) const {
return t + x;
}
private:
int x;
};
int main() {
vector<int> v1 = {1, 2, 3, 4, 5};
vector<int> v2(v1.size());
add_x add42(42);
add_x add21(21);
add_x add100(100);
transform(v1.begin(), v1.end(), v2.begin(), add42);
transform(v1.begin(), v1.end(), v2.begin(), add21);
transform(v1.begin(), v1.end(), v2.begin(), add100);
return 0;
}
参考
- 侯捷《面向对象高级编程(下)》
- What are C++ functors and their uses?
网友评论