C++的局部类是一种异常灵活的东西。嗯,就好像是原生动物门的草履虫一样的单细胞生物。现在来看看它的用途。
一、当作局部函数用。很多新语言都支持了局部函数。就是在函数体的内部还可以定义函数。原则上C和C++语言是不支持局部函数的。也不能说这么绝对,后来加入的lamda语法可以看作C++语言支持了局部函数。它跟这里讨论的用法有异曲同工之处。在函数内部定义一个纯内联的局部类,让它重载()运算符:
#include <stdio.h>
int main()
{
class {
public:
void operator()(int n) {
printf("%d: %d\n", ++i, n);
}
void init() {i=0;}
int i;
} print;
print.init();
print(100);
print(20000);
return 0;
}
这个print仿函数就相当于局部函数。它几乎可以定义在函数体的任何地方。用起来也很不错。
二、一次性转接口。假设有个鸟类的接口:
class bird {
public:
virtual void fly();
...
};
而动画片有个函数play(bird &b), 用到了bird的fly(); 全篇有很多种鸟,它们都继承了bird这个基础类。到这里为止,一切都好。有一只蜜蜂。全剧本只有一只蜜蜂。它也会飞, 但是没有继承鸟类。因为只有一只, 你不想再为它单独写个play了。
#include <stdio.h>
class bird {
public:
virtual void fly() {}
};
class swallow :public bird {
public:
void fly(){ printf("swallow fly!\n"); }
};
class animator {
public:
void play(bird &b) {
b.fly();
}
};
class bee {
public:
void fly() {printf("-bee isn't a bird, but can fly.\n");}
};
int main()
{
animator a;
swallow s;
bee b;
a.play(s);
//a.play(b);
class whatever:public bird {
bee &b;
public:
whatever(bee &b):b(b){}
void fly() { b.fly(); }
};
whatever b4bird(b);
a.play(b4bird);
}
这会打印出:
swallow fly!
-bee isn't a bird, but can fly.
这里的局部类whatever起到了一次性接口转换的作用。都说C++的接口是"侵入"式接口。掌握了一次性接口转换的这种用法,"侵入"式接口用起来也没什么。
要是那个一次性转换接口能直接写在参数表上就更好了,可惜编译通不过。
int main()
{
animator a;
swallow s;
bee b;
a.play(s);
a.play(
class whatever:public bird {
bee &b;
public:
whatever(bee &b):b(b){}
void fly() { b.fly(); }
} b4bird(b);
);
}