zoukankan      html  css  js  c++  java
  • C++ 模式设计

     只写了MinGw/Linux API部分。所有相关的代码都是参考C++ API

    C++ 11智能指针参考http://blog.csdn.net/zy19940906/article/details/50470087

    <1>Pimpl 

    pointer to the implementation

    计算一个累构造消耗的时间。

    AutoTimer.h

    //
    // Created by Administrator on 2017/3/26.
    //
    
    #ifndef MODERN_DESIGN_AUTOTIMER_H
    #define MODERN_DESIGN_AUTOTIMER_H
    #include <iostream>
    #include <string>
    #include <memory> class AutoTimer { public: explicit AutoTimer(const std::string &name); ~AutoTimer(); private: class Impl; Impl *_mimpl;
    // std::unique_ptr <Impl> _mimpl; //智能指针,生命周期与类成员周期相同 };
    #endif //MODERN_DESIGN_AUTOTIMER_H

    AutoTimer.cpp

    #include "AutoTimer.h"
    #include <sys/time.h>
    class AutoTimer::Impl
    {
    public:
        double getElapsed() const
        {
            timeval end_time;
            gettimeofday(&end_time,NULL);
            double t1 = _start_time.tv_usec / 1e6 + _start_time.tv_sec;
            double t2 = end_time.tv_usec / 1e6 + end_time.tv_sec;
            return t2 - t1;
        }
        std::string _name;
        timeval _start_time;
    };
    AutoTimer::AutoTimer(const std::string &name):_mimpl(new AutoTimer::Impl())
    {
        _mimpl->_name = name;
        gettimeofday(&_mimpl->_start_time,NULL);
    }
    AutoTimer::~AutoTimer()
    {
        std::cout << _mimpl->_name << ":took " << _mimpl->getElapsed() << " secs" <<std::endl;
        delete _mimpl; // 如果是智能指针不需用
        _mimpl= NULL;  // 如果是智能指针不需用
    }

    main.cpp:

    AutoTimer timer("Houdini");
    AutoTimer timer2("Maya");

    输出:

    Maya:took 0.000999928 secs
    Houdini:took 0.000999928 secs

    C语言的不透明指针。。。。实现就是这么轻松随意。。。。

    AutoTimer.h

    #ifndef MODER_DESIGN_C_AUTOTIMER_H
    #define MODER_DESIGN_C_AUTOTIMER_H
    // 声明一个指向AutoTimer结构体不透明的指针
    typedef struct AutoTimer *AutoTimerPtr;
    AutoTimerPtr AutoTimerCreate(const char *name);
    void AutoTimerDestroy(AutoTimerPtr ptr);
    
    
    #endif //MODER_DESIGN_C_AUTOTIMER_H

    AutoTimer.cc

    #include "AutoTimer.h"
    #include <sys/time.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    struct AutoTimer
    {
        char *mName;
        timeval mStartTime;
    };
    
    AutoTimerPtr AutoTimerCreate(const char *name)
    {
        AutoTimerPtr ptr = static_cast<AutoTimerPtr> (malloc(sizeof(AutoTimer))); // 因为我们用的是C++编译器,所以还是显式转换
        if(ptr)
        {
            ptr->mName = strdup(name);
            gettimeofday(&ptr->mStartTime,NULL);
        }
        return ptr;
    }
    static double GetElapsed(AutoTimerPtr ptr)
    {
        timeval end_time;
        gettimeofday(&end_time,NULL);
        double t1 = ptr->mStartTime.tv_usec / 1e6 + ptr->mStartTime.tv_sec;
        double t2 = end_time.tv_usec / 1e6 + end_time.tv_sec;
        return t2-t1;
    }
    void AutoTimerDestroy(AutoTimerPtr ptr)
    {
        if(ptr)
        {
            printf("%s took %f secs
    ",ptr->mName,GetElapsed(ptr));
            free(ptr);
        }
    }

    main.cpp

    AutoTimerPtr ptr = AutoTimerCreate("Houdini");
    AutoTimerDestroy(ptr);

    AutoTimerPtr ptr2 = AutoTimerCreate("Maya");
    AutoTimerDestroy(ptr2);

    输出:

    Houdini took 0.000000 secs
    Maya took 0.000000 secs
    Hello, World!

    <2> 单例模式:

    #include <iostream>
    #include <thread>
    #include <mutex>
    using namespace std;
    
    class Singleton
    {
    public:
    
        static Singleton &GetInstance()
        {
            static Singleton *instance  = NULL;
            if(! instance)
            {
                std::mutex mutex;
                if(! instance)
                {
                    instance = new Singleton();
                }
                mutex.unlock();
            }
            return *instance;
        }
        static Singleton *GetInstancev2()
        {
            static Singleton m_instance;
            return &m_instance;
        }
    
    
    private:
        Singleton()
        {
    
        }
        ~Singleton()
        {
    
        }
        Singleton(const Singleton &);
        const Singleton &operator=(const Singleton &);
    
    
    };
    
    void threadFunc(string name,int uniqueId)
    {
        std::cout << "Singleton meomery:" << name << " -> " << uniqueId << " :Object &"<<&Singleton::GetInstance() <<"
    ";
    }
    void threadRun()
    {
        thread thread_01(threadFunc,"houdini",0);
        thread thread_02(threadFunc,"maya",1);
        thread thread_03(threadFunc,"blender",2);
    
        thread_01.join();
        thread_02.join();
        thread_03.join();
    
    
    }
    
    
    int main()
    {
        Singleton &obj = Singleton::GetInstance();
        std::cout << &obj <<std::endl;
        //
        std::cout << "test in thread 
    ";
        threadRun();
        
        // test use another
        std::cout << "GetInstancev2 method create 
    ";
        Singleton *obj2 = Singleton::GetInstancev2();
        std::cout << obj2 <<std::endl;
    
        Singleton *obj3 = Singleton::GetInstancev2();
        std::cout << obj3 << std::endl;
        return 0;
    }
    View Code

    输出:

    0x3e67c0
    test in thread
    Singleton meomery:Singleton meomery:blender -> Singleton meomery:maya -> houdini -> 0 :Object &0x3e67c0
    1 :Object &0x3e67c0
    2 :Object &0x3e67c0
    GetInstancev2 method create
    0x4060b0
    0x4060b0

    <3> 工厂模式

    <4> 写时复制,节省内存最好的方法就是确实需要时再分配。所有客户共享一份唯一的资源,直到其中一个想修改这份资源为止,只有在哪个时间点才回构造副本.

    template <class T> class CowPtr
    {
    public:
        using RefPtr = std::shared_ptr<T> ;
        inline CowPtr():mPtr(0){}
        inline CowPtr(const CowPtr<T> &other):mPtr(other.mPtr)
        {
            std::cout << "copy function "<< __LINE__<< "
    ";
        }
        inline explicit CowPtr(T *other):mPtr(other){}
        inline T &operator*()
        {
            std::cout<< "inline T &operator*()" <<__LINE__<<std::endl;
            Detach();
            return *(mPtr.get());
        }
        inline const T &operator*() const {
            std::cout<< "inline const T &operator*() const" <<__LINE__<<std::endl;
            return *(mPtr.get());
        }
        inline T*operator->()
        {
            std::cout<< "inline T*operator->()" <<__LINE__<<std::endl;
            Detach();
            return mPtr.get();
        }
        inline const T*operator->() const {
            std::cout<< "inline const T*operator->() " << __LINE__<<std::endl;
            return mPtr.get();
        }
    
        inline const T*data()const
        {
            std::cout<< "inline const T*data()const " << __LINE__<<std::endl;
            return mPtr.get();
        }
    
    
        inline bool operator==(const CowPtr<T> &other) const {
            return mPtr.get() == other.mPtr.get();
        }
    
        inline bool operator!() const
        {
            return !mPtr.get();
        }
        inline CowPtr &operator=(T *other)
        {
            mPtr = RefPtr(other);
            return *this;
        }
    
    
    private:
        inline void Detach()
        {
            T *temp = mPtr.get();
            if(temp && !mPtr.unique())
            {
                mPtr = RefPtr(new T(*temp)); //
            }
        }
        RefPtr  mPtr;
    
    };
    
    class WriteOnCopy
    {
    public:
        WriteOnCopy(){}
        std::string getValue() const
        {
            return *mData;
    
        }
        void setValue(const std::string &value)
        {
            mData = new std::string(value);
        }
    
    private:
        CowPtr<std::string> mData;
    };
    
    
    
    
    int main()
    {
        CowPtr<std::string> string1(new std::string("houdini"));
        CowPtr<std::string> string2(string1);  //copy function
        CowPtr<std::string> string3(string1);  //copy function
        string3->append("!!");
        std::cout  << *string3.data()<<std::endl;  //houdini!!
        std::cout  << *string1<<std::endl; // houdini
    
    
        std::cout << "
     after change 1 
    ";
        CowPtr<std::string> pr_string1(new std::string("share me"));
        char &char_ref = pr_string1->operator[](1); //use the string operator[] function
        CowPtr<std::string> pr_string2(pr_string1);
        char_ref = 'H'; // after change 'H'
        std::cout  << *(pr_string1.data())<<std::endl;  //sHare me
        std::cout  << *(pr_string2.data())<<std::endl;  //sHare me
    
    
        // use write on copy
        std::cout << "
    write on copy
    ";
        WriteOnCopy obj1;
        obj1.setValue("hello");
        WriteOnCopy obj2 = obj1;
        std::string val = obj2.getValue();
        WriteOnCopy obj3 = obj1;
        obj3.setValue("There");
        std::cout << "obj1 get data " << obj1.getValue() <<std::endl;
        std::cout << "obj2 get data " << obj2.getValue() <<std::endl;
        std::cout << "obj3 get data " << obj3.getValue() <<std::endl;
    
    
        return 0;
    }
    View Code

    <5>CPP Style

    (1)更好的重载operator

    GLY_Currency.h

    #ifndef CPPSTYLE_GLY_CURRENCY_H
    #define CPPSTYLE_GLY_CURRENCY_H
    
    #include <memory>
    #include <iostream>
    class GLY_Currency
    {
    public:
        explicit GLY_Currency(int value);
        ~GLY_Currency();
        GLY_Currency(const GLY_Currency&obj);
        int getValue()const;
    
    // these operators must be declared as member functions
        GLY_Currency &operator =  (const GLY_Currency &rhs);
        GLY_Currency &operator += (const GLY_Currency &rhs);
        GLY_Currency &operator -= (const GLY_Currency &rhs);
        GLY_Currency &operator *= (const GLY_Currency &rhs);
        GLY_Currency &operator /= (const GLY_Currency &rhs);
    
    private:
        class Impl;
        std::unique_ptr <Impl> mImpl;
    };
    
    
    // these operators can (and should) be declared as free functions
    inline GLY_Currency operator+(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        // 复制一份是因为lhs+=rhs 会导致 lhs更改数据,因为lhs是const,所以不用复制构造,会导致
        // 编译错误
        return GLY_Currency(lhs)+=rhs;
    }
    inline GLY_Currency operator-(const GLY_Currency &lhs ,const GLY_Currency &rhs)
    {
        return GLY_Currency(lhs)-=rhs;
    }
    inline GLY_Currency operator*(const GLY_Currency &lhs ,const GLY_Currency &rhs)
    {
        return GLY_Currency(lhs)*=rhs;
    }
    GLY_Currency operator /(const GLY_Currency &lhs, const GLY_Currency &rhs)
    {
        return GLY_Currency(lhs) /= rhs;
    }
    
    
    inline bool operator==(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        return lhs.getValue()==rhs.getValue();
    }
    
    inline bool operator!=(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        return !(lhs==rhs);
    }
    inline bool operator<(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        return rhs.getValue()<rhs.getValue();
    }
    inline bool operator>(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        return rhs < lhs;
    }
    
    inline bool operator<=(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        return !(rhs > rhs);
    }
    inline bool operator>=(const GLY_Currency &lhs,const GLY_Currency &rhs)
    {
        return rhs <= lhs;
    }
    
    inline std::ostream &operator <<(std::ostream &os,const GLY_Currency &rhs)
    {
        os << rhs.getValue();
        return os;
    }
    
    
    
    #endif //CPPSTYLE_GLY_CURRENCY_H
    View Code

    GLY_Currency.cpp

    //
    // Created by Administrator on 2017/5/2.
    //
    
    #include "GLY_Currency.h"
    class GLY_Currency::Impl
    {
    public:
        int mValue;
    };
    
    
    
    GLY_Currency::GLY_Currency(int value):mImpl(new Impl)
    {
        mImpl->mValue = value;
    }
    GLY_Currency::~GLY_Currency() {
    
    }
    
    GLY_Currency::GLY_Currency(const GLY_Currency &obj):mImpl(new Impl)
    {
        mImpl->mValue = obj.mImpl->mValue;
    }
    int GLY_Currency::getValue() const {
        return mImpl->mValue;
    }
    
    GLY_Currency& GLY_Currency::operator=(const GLY_Currency &rhs) {
        if (this != &rhs)
        {
            mImpl->mValue = rhs.mImpl->mValue;
        }
        return *this;
    }
    GLY_Currency& GLY_Currency::operator-=(const GLY_Currency &rhs) {
        mImpl->mValue -= rhs.mImpl->mValue;
        return *this;
    }
    GLY_Currency& GLY_Currency::operator+=(const GLY_Currency &rhs) {
        mImpl->mValue += rhs.mImpl->mValue;
        return *this;
    }
    
    GLY_Currency& GLY_Currency::operator*=(const GLY_Currency &rhs) {
        mImpl->mValue *= rhs.mImpl->mValue;
        return *this;
    }
    GLY_Currency& GLY_Currency::operator/=(const GLY_Currency &rhs) {
        mImpl->mValue /= rhs.mImpl->mValue;
        return *this;
    }
    View Code

    <6>Exception Basic

    #include <iostream>
    
    
    /*
    // BASIC
    template <typename T>
    T safe_divide(T const&a,T const &b)
    {
        if (b == 0)
        {
            const char *error = "b is zero do not allowed ";
            throw error;
        }
        return a/b;
    }
    
    int main()
    {
        double result = 0.0 ;
        try
        {
            result = safe_divide(2.0,0.0);
        }
        catch (const char*s)
        {
            std::cout << s <<std::endl; // will get const char *error = "b is zero do not allowed "
    
            //try to use right arg
            result = safe_divide(2.0,1.0);
        }
    
        std::cout << result <<std::endl;
        return 0;
    }*/
    
    
    
    // Use class handle the error
    class ClassBad_divide_Except
    {
    private:
        double v1;
        double v2;
    public:
        ClassBad_divide_Except(double a=0.0,double b=0.0):v1(a),v2(b){
    
        }
        void mesg()
        {
            const char* mesgs = "Error divide argments :";
            std::cout <<mesgs << v1<<"/"<<v2<<std::endl;
        }
    };
    
    
    template <typename T>
    T safe_divide(T const&a,T const &b)
    {
        if (b == 0)
        {
            const char *error = "b is zero do not allowed ";
            throw ClassBad_divide_Except(a,b); //emit a class instance ClassBad_divide_Except()
        }
        return a/b;
    }
    
    
    int main()
    {
        double result = 0.0 ;
        try
        {
            result = safe_divide(2.0,0.0);
        }
        catch (ClassBad_divide_Except &did) // get class ref
        {
            did.mesg(); // get error message
    
            //try to use right arg
            result = safe_divide(2.0,1.0);
        }
    
        std::cout << result <<std::endl;
        return 0;
    }
    View Code

    <7> RTTI

    RTTI just compatable for a class have a virtual method  

  • 相关阅读:
    「manacher」
    「回文自动机」
    「可持久化数据结构(平衡树、trie树、线段树) 」
    「后缀数组」
    「LCT」
    「网络流」
    「一些知识点」
    「至今不会」
    「推荐博客」
    「最小生成树」
  • 原文地址:https://www.cnblogs.com/gearslogy/p/6623422.html
Copyright © 2011-2022 走看看