摸索现代C++风格

来源:互联网 发布:javascript 书 知乎 编辑:程序博客网 时间:2024/04/29 19:33
/** * 摸索现代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));// lambdaapp->use([](void * arg){std::cout << "Handler from lambda expression" << std::endl;});app->handle((void*)200);return 0;}

</pre><pre>
                                             
0 0