/**
* 摸索现代C++风格
* C++11确实带来很多新鲜空气
* 有些特性的使用立即可以使代码有很大的改观
* shared_ptr,function,bind,lambda,都是极好的东西
* 今天挑选这几个特性进行一些摸索尝试,来试探我们应该如何走向现代C++
* 虽然C++有很多铁杆粉丝,但有精华,也免不了糟粕吧,所以期待类似The Good part of javascript类似的
* 书籍,也许名字就叫做The good part of c++。我们确实需要这样一本书,但我深想一下,这本书似乎又应该叫《The bad part of C++》
* 为什么这么说呢,javascript第一眼的感觉就是太灵活和混乱,就是bad part太多了,以至于我们应该把good part 挑选出来,而把其他丢弃。
* js凭借其部分的优秀部分,似乎就已经有了很好的建设性。
* 反过来看C++,似乎bad part远没有js多,可是其造成的破坏和混乱似乎一点都不必js少,这也是一个很难理解的现象。
* C++语言太过庞大,标准库太过苍白
* C++语言没有占领导地位的编程风格,没有样本代码(如果说把STL和Boost当样板代码,我认为绝对实在陷害那些大师,因为这绝非他们的本意)
* 换句话说,STL和boost的代码我们可以认为是大师们是在走投无路的情况下做出的决策,很精妙,但却不能当做典范。
* C++典范,我至今没有找到,在摸索现代C++风格的同时,我们也同时去寻找C++典范。
* 虽然STL的实现代码完全不能作为典范,但STL外部接口却具有极大的参考意义,甚至可以说其外部接口还是非常优雅,概念上也具有极强的一致性
* 探索C++典范,STL绝对是一个不能忽略的部分。
* 1.有帮助的约定
* 2.命名规范
* 3.资源管理
*
*/
#include <iostream>
#include <functional>
#include <memory>
#include <list>
/**
* 接口定义,通过纯虚类模拟JAVA interface
* 命名采用以I开头的大驼峰命名规则
*/
// IAspect 代表应用处理的一个方面
// 接口包含before和after方法
class IAspect{
public:
typedef std::shared_ptr<IAspect> Pointer;
typedef std::weak_ptr<IAspect> WeakPointer;
virtual void before() = 0;
virtual void after() = 0;
};
/**
* Application 实现一个简单的应用基本框架
* 在这个框架中,可以注册一系列的处理方法,
* 框架处理时,依次调用注册的方法进行处理
*/
//类型名称采用大驼峰命名规则
class Application
{
protected:
//第一个尝试。约定所有类的构造函数全部问ptotected,阻止用户自己构造对象,但不阻止继承
//对象的构造统一由create方法完成,返回一个本对象的智能指针,由此引出了第一个尝试:强制使用智能指针,由此带来的问题,在最后再来讨论
//产生的结果就是对象只会在堆上分配,由智能指针来管理
//也算是C++在程序员管理内存和机器自动管理内存直接的一个折衷方法,程序员在内存管理上所有的任务就是通过使用shared_ptr和weak_ptr,保证对象间不出现循环引用现象。
//
Application() = default;
public:
//所有类均定义Pointer和WeakPointer两种类型
typedef std::shared_ptr<Application> Pointer;
typedef std::weak_ptr<Application> WeakPointer;
typedef std::function<void(void)> AspCallback;
typedef std::function<void(void*)> Handler;
static Pointer create(){
return Pointer(new Application());
}
void use(Handler handler){
handlers.push_back(handler);
}
void use(IAspect::Pointer asp){
befor(std::bind(&IAspect::before, asp));
after(std::bind(&IAspect::after, asp));
}
void befor(AspCallback cb){
befores.push_back(cb);
}
void after(AspCallback cb){
afters.push_back(cb);
}
void handle(void * arg){
for (auto fun : befores){
fun();
}
for (auto fun : handlers){
fun(arg);
}
for (auto fun : afters){
fun();
}
}
private:
std::list<AspCallback> afters;
std::list<AspCallback> befores;
std::list<Handler> handlers;
};
void befor1(){
std::cout << "Defualt Before" << std::endl;
}
void after1(){
std::cout << "Defualt After" << std::endl;
}
void handle1(void * args){
std::cout << "Defualt Handle" << std::endl;
}
void handle2(void* args){
int intArg = (int)args;
std::cout << "Handle With int args:" << intArg << std::endl;
}
class Aspect1{
protected:
Aspect1() = default;
public:
static void befor(){
std::cout << "Aspect1 Before" << std::endl;
}
static void after(){
std::cout << "Aspect1 After" << std::endl;
}
};
class Aspect2{
protected:
Aspect2() = default;
public:
typedef std::shared_ptr<Aspect2> Pointer;
typedef std::weak_ptr<Aspect2> WeakPointer;
void befor(){
std::cout << "Aspect2 Before" << std::endl;
}
void after(){
std::cout << "Aspect2 After" << std::endl;
}
static Pointer create(){
return Pointer(new Aspect2());
}
};
class MyAspect :public IAspect{
protected:
MyAspect(int val) :value(val){};
public:
virtual void before(){
std::cout << "MyAspect before with value:" << value << std::endl;
}
virtual void after(){
std::cout << "MyAspect after with value:" << value << std::endl;
}
static Pointer create(int val){
return Pointer(new MyAspect(val));
}
private:
int value;
};
int main(int argc, char* argv[])
{
std::cout << "begin testing.." << std::endl;
auto app = Application::create();
app->befor(befor1);
app->after(after1);
app->use(handle1);
app->use(handle2);
app->handle((void *)100);
app->befor(Aspect1::befor);
app->after(Aspect1::after);
auto asp2Ptr = Aspect2::create();
app->befor(std::bind(&Aspect2::befor, asp2Ptr));
app->after(std::bind(&Aspect2::after, asp2Ptr));
app->use(MyAspect::create(110));
// lambda
app->use([](void * arg){
std::cout << "Handler from lambda expression" << std::endl;
});
app->handle((void*)200);
return 0;
}
</pre><pre>