CPP design mode learning

Source address: https://www.ev0l.art/index.php/archives/20/

Memo mode

  • A pattern that records the snapshot state of another class within one class. It can be used to jump back at the right time
  • There are three steps in the design memo:
  1. Node of design record, storage record
    2. Storage of design records: vector list map set can make the list array tree

3. Operation record class, record node status, set node status and display node status

Strategy mode

  • Policy pattern encapsulates each algorithm into an independent class with a common interface for a group of algorithms.
  • So that they can transform each other, and the policy mode can change the algorithm without affecting the client. Policy patterns separate behavior from environment, and environment classes are responsible for maintaining and querying behavior classes.
  • Policy pattern depends on polymorphism. The pointer of abstract class, interface and abstract class of policy pattern can access all subclass objects (pure virtual function)
  • Implementation classes of various policies. Must integrate abstract classes.
  • Setting interface class for policy. Set different policies

Design pattern abstract factory pattern

  • Factory mode: customer class and factory class are separated.
  • Consumers need any product, just ask for it from the factory.
  • Consumers can accept new products without modification. The disadvantage is that when the product is modified, the factory class also needs to make corresponding modification

=======

Design pattern

Simple factory mode

  • Base class store data derived class store operation
  • Another static class that calls each operation is implemented, and the derived class pointer is returned when calling

Code:

#include <iostream>
#include <string>

using namespace std;

class OP
{
public:
    double a;
    double b;
    virtual double jisuan()
    {
        return 0;
    }
};

class add : public OP
{
    double jisuan()
    {
        return a + b;
    }
};

class sub : public OP
{
    double jisuan()
    {
        return a - b;
    }
};

class divv : public OP
{
    double jisuan()
    {
        return a / b;
    }
};

class mul : public OP
{
    double jisuan()
    {
        return a * b;
    }
};

class Fac
{
public:
    static OP *selectop(char c)
    {
        switch (c)
        {
        case '+':
            return new add();
            break;

        case '-':
            return new sub();
            break;

        case '*':
            return new mul();
            break;

        case '/':
            return new divv();
            break;

        default:
            printf("you entered wrong caculation!!");
            break;
        }
    }
};

int main(void)
{
    OP *opr = Fac::selectop('/');
    opr->a = 100;
    opr->b = 5;
    cout << opr->jisuan() << endl;

    return 0;
}

 

Method factory mode

  • Abstract the classes of operation and instance factory
  • Implementing different operations by inheriting abstract classes
  • Method factory pattern is a simple factory pattern that abstracts and encapsulates the factory

Code:

#include <iostream>
#include <string>
using namespace std;


class OP
{
public:
    double a, b;
    virtual double jisuan()
    {
        return 0;
    }
};

class add : public OP
{
    double jisuan()
    {
        return a + b;
    }
};

class sub : public OP
{
    double jisuan()
    {
        return a - b;
    }
};

class divv : public OP
{
    double jisuan()
    {
        return a / b;
    }
};

class mul : public OP
{
    double jisuan()
    {
        return a * b;
    }
};

class IFac
{
private:
    /* data */
public:
    virtual OP *selectop() = 0;
};

class addop : public IFac
{
public:
    static OP *selectop()
    {
        return new add();
    }
};

class subop : public IFac
{
public:
    static OP *selectop()
    {
        return new sub();
    }
};

class divop : public IFac
{
public:
    static OP *selectop()
    {
        return new divv();
    }
};

class mulop : public IFac
{
public:
    static OP *selectop()
    {
        return new mul();
    }
};

int main(void)
{
    IFac *opp = mulop::selectop();
    opp->a=90;
    opp->b=100;
    cout << opp->jisuan()<<endl;
    return 0;
}

 

 

Abstract factory pattern

  • Factory mode: customer class and factory class are separated.
  • Consumers need any product, just ask for it from the factory.
  • Consumers can accept new products without modification. The disadvantage is that when the product is modified, the factory class also needs to make corresponding modification
  • Consumer factory products all have their own abstract classes and provide different services by inheriting and instantiating abstract interfaces

Singleton mode

  • Singleton pattern confirms that a class has only one instance
  • There are two implementation modes: 1. Declaration of anonymous class 2. Implementation through internal static class pointer
  • Singleton mode: Singleton mode ensures that a class has only one instance,
  • And instantiate and provide the single instance mode to the whole system
  • The singleton pattern should only be used when there is a real "Singleton" requirement.
    public:
    int a=100;
    }aa;

#include <iostream>
#include <string>

class
{
public:
    int a = 100;
} aa;

class SingleInstance
{
private:
    /* data */

    int i = 0;

public:
    static SingleInstance *instance;
    SingleInstance(int a)
    {
        this->i = a;
    }

    static SingleInstance *get_instance()
    {
        return instance;
    }
};

SingleInstance *SingleInstance::instance = new SingleInstance(1995);


class B:public SingleInstance
{

};

int main(void)
{
    SingleInstance *s1=SingleInstance::get_instance();
    SingleInstance *s2=B::get_instance();

    std::cout<<(s1==s2)<<std::endl;

    std::cin.get();

    return 0;
}

 

proxy pattern

  • Proxy mode: proxy mode provides a proxy object for an object,
  • And the proxy object controls the reference to the source object.
  • An agent is a person or an agency acting on behalf of another person or agency.
  • In some cases, the customer does not want or can not directly refer to an object,
  • The proxy object can directly mediate between the client and the target object.
  • The client cannot distinguish between the agent subject object and the real subject object.
  • The proxy mode can not know the real proxy object,
  • However, the proxy object cannot create a proxy object when it only holds an interface of the proxy object,
  • The proxy object must be created and passed in by another role of the system.
#include <iostream>
#include <string>

using namespace std;

class  girl
{
public:
     girl(string);
     girl();
    ~ girl();
    string name;
private:

};

 girl:: girl(string s1)
{
     name = s1;
}

 girl::~ girl()
{
}

 girl::girl()
 {
     name = "Unknown!";
 }


 class gift {
 public:
     virtual void gift1() = 0;
     virtual void gift2() = 0;
 };


 class gg:public gift
 {
 public:
     gg(girl);
     ~gg();


    void gift1()
     {
         cout << mm.name << "Present to you 1" << endl;
     }

    void gift2()
    {
        cout << mm.name << "Present to you 2" << endl;
    }
 private:
     girl mm;
 };

 gg::gg(girl m)
 {
     mm = m;
 }

 gg::~gg()
 {
 }



 class proxy :public gift
 {
 private :
     gg gg1;

 public:

     proxy(girl mm) :gg1(mm)
     {

     }

     void gift1()
     {
         gg1.gift1();
     }

     void gift2()
     {
         gg1.gift2();
     }
 };



int main(void)
{

    girl mm1("Little sister");
    proxy p1(mm1);
    p1.gift1();
    p1.gift2();


    cin.get();


    return 0;
}

 

 

Iterator mode

  • Iterative subpattern: the iterative subpattern can access elements in an aggregation in sequence without exposing the internal representation of the aggregation.
  • The aggregation of multiple objects is called aggregation. Aggregation objects are container objects that can contain a group of objects.

Command line mode

  • Create a separate class to execute the command. Full time execution of orders
  • The executor of the command specially creates a base class from which the classes for executing different commands inherit. Divide by executing different commands.
  • Create another class to coordinate these classes, and call the class that executes the command.
  • Code:
  • Command mode sample code
#include <iostream>
#include <string>
#include <list>

using namespace std;



class doing
{
public:

    void action1() {
        cout << "lalala Ate" << endl;
    }

    void action2()
    {
        cout << "It's time to exercise!!!!!" << endl;
    }
private:

};

class  Command
{

public:
    Command(doing * d) {
        reciver = d;
    }

    virtual void do_doing() = 0;

    protected:
        doing* reciver;

        

};


class action1_command:public Command
{
public:
    action1_command(doing* d) :Command(d)
    {

    }

    void do_doing()
    {
        reciver->action1();
    }

};

class action2_command :public Command
{
public:
    action2_command(doing* d) :Command(d)
    {

    }

    void do_doing()
    {
        reciver->action2();
    }

};

class waiter
{
public:

    void set_action(Command* c)
    {
        this->command = c;
    }

    void do_action()
    {
        this->command->do_doing();
    }

protected:
    Command* command;

};

class waiter_n {

public:
    void set_action(Command* c)
    {
        this->command.push_back(c);
    }

    void do_action()
    {
        auto n = command.begin();
        while (n!=command.end())
        {
            (*n)->do_doing();
            n++;
        }
    }

private:
    list<Command*> command;
};


int main(void)
{
    doing* dd = new doing();
    Command* action_command1 = new action1_command(dd);
    Command* action_command2 = new action2_command(dd);
    waiter* w = new waiter();
    w->set_action(action_command1);
    w->do_action();
    w->set_action(action_command2);
    w->do_action();
    cout << endl;
    waiter_n* ww = new waiter_n();
    ww->set_action(action_command1);
    ww->set_action(action_command2);
    ww->do_action();
    return 0;
}

 

 

Responsibility chain mode:

  • One level communicates the other level, knowing that there is no superior, until the highest level
  • Example of responsibility chain model
#include <iostream>
#include <string>


using namespace std;

class  Request
{
public:
    string request_name;
    string request_type;
    int n;
private:
    
};


class Manager {
public:
    Manager(string n, string j, int id)
    {
        name = n;
        job = j;
        classid = id;
    }

    void setSuper(Manager *p)
    {
        this->super = p;
    }

    virtual void  apply(Request*) = 0;
    int classid;
    Manager* super;
    string name;
    string job;
private:

    
    
};

class  zhuguan:public Manager
{
public:
    zhuguan(string n,  int id) :Manager(n,"Executive director", id) {}

    void apply(Request* r)
    {
        if (r->n > this->classid)
        {
            cout << r->request_type << "\t" << r->request_name << "\t cover" << this->job << this->name << "Review! No permission, will continue to submit!!" << "classid=" << this->classid << endl;
            super->apply(r);
        }
        else
        {
            cout << r->request_type << "\t" << r->request_name << "\t cover"<<this->job<<this->name<<"approval!!!"<<"classid="<<this->classid<< endl;
        }
    }

private:

};

class  zongjian :public Manager
{
public:
    zongjian(string n, int id) :Manager(n, "Chief inspector", id) {}

    void apply(Request* r)
    {
        if (r->n > this->classid)
        {
            cout << r->request_type << "\t" << r->request_name << "\t cover" << this->job << this->name << "Review! No permission, will continue to submit!!" << "classid=" << this->classid << endl;
            super->apply(r);
        }
        else
        {
            cout << r->request_type << "\t" << r->request_name << "\t cover" << this->job << this->name << "approval!!!" << "classid=" << this->classid << endl;
        }
    }

private:

};


class  zongjingli :public Manager
{
public:
    zongjingli(string n) :Manager(n, "General manager", 1000) {}

    void apply(Request* r)
    {
        
            cout << r->request_type << "\t" << r->request_name << "\t cover" << this->job << this->name << "approval!!!" << "classid=" << this->classid << endl;
        
    }

private:

};


int main(void)
{
    Request* request = new Request();
    request->request_name = "Sick please take 10 days off";
    request->request_type = "sick leave";
    request->n = 50;

    zhuguan* zg = new zhuguan("Xiaofang", 10);
    zongjian* zj = new zongjian("Xiao Ming", 30);
    zongjingli* zjl = new zongjingli("Boss");
    zg->setSuper(zj);
    zj->setSuper(zjl);

    zg->apply(request);
    return 0;
}

 

 

20140903 data structure and algorithm

Overview

An introduction to

Characteristics of the algorithm

Metrics for algorithms

Boost and algorithm

First boost program of boost Array

  • To use boost, you must download and install the appropriate compiled package.
  • Different versions of VS are used
  • Linux can only compile by itself
  • The namespace of boost is boost
  • boost first program (array)
#include <iostream>
#include <boost/array.hpp>
#include <string>

using namespace std;

int main(void)
{
    boost::array<int,10> arr = { 0,1,2,3,4,5,6,7,8,9 };

    boost::array<int, 10>::iterator ib = arr.begin();
    boost::array<int, 10>::iterator ie = arr.end();

    for (;ib!=ie;ib++)
    {
        cout << *ib << endl;
    }

    cin.get();
    return 0;
}

 

 

Study of boost library

std mode
  • Bind the existing function to add new parameters but not change the original function (std mode)
  • Use:

    • 1. The class to perform the operation inherits from STD:: binary_function < >
    • 2. Use bind1st()
  • Code:

    • Bind1st sample code (bind1st.cpp)
#include <iostream>
#include <string>
#include <functional>
#include <list>
#include <algorithm>
#include "boost/bind.hpp"

using namespace std;
using namespace boost;

class jia:public binary_function<int,int,void>
{
public:
void operator ()( int i, int j) const
{
    cout << i+j << endl;
}

private:

};



int main(void)
{
    list <int> ls1;
    ls1.push_back(5);
    ls1.push_back(15);
    ls1.push_back(125);

    for_each(ls1.begin(), ls1.end(), bind1st(jia(),10));


    cin.get();
    return 0;
}

 

 
boost mode
  • boost::bind sample code
#include <iostream>
#include <string>
#include <functional>
#include <list>
#include <algorithm>
#include "boost/bind.hpp"

using namespace std;
using namespace boost;

class jia:public binary_function<int,int,void>
{
public:
void operator ()( int i, int j) const
{
    cout << i+j << endl;
}

private:

};

void add(int i, int j)
{
    cout << i + j << endl;
}


int main(void)
{
    list <int> ls1;
    ls1.push_back(5);
    ls1.push_back(15);
    ls1.push_back(125);

    //std mode
    for_each(ls1.begin(), ls1.end(), bind1st(jia(),10));

    //boost mode
    for_each(ls1.begin(), ls1.end(), bind(add,13, _1));
    cin.get();
    return 0;
}

 

boost::function library

  • The boost::function library provides a class template, boost::function. It is a generic function class, used to encapsulate various function pointers, which are usually used in combination with bind. When the functor is not bound with any pointers, a boost::bad_function_call exception will be thrown.

boost::ref

  • Cannot copy object with boost::ref()

RAII

  • Avoid memory leakage and use the memory on the heap as a stack

smartpointers Library

Virtual function table of class

  • Class has a virtual function table that stores the addresses of all virtual functions.
  • Class always puts the virtual function table first
  • A method to access the virtual function of a class (the code is as follows:)
  • No matter whether the base class is public or private, it does not affect the sub class integration virtual function
  • Virtual function order: base class
  • Multiple inherited subclasses will have multiple virtual function tables, and each virtual function table inherits from the virtual function table of each base class
#include <iostream>

using namespace std;

class A
{
public:


    void virtual a() {
    
        std::cout << "A --> a" << endl;
    }

    void virtual b() {

        std::cout << "A--> b" << endl;
    }

    void virtual c() {

        std::cout << "A--> c" << endl;
    }
private:

};


class B :public A
{
public:
    void virtual a()
    {
        std::cout << "B--> a" << endl;
    }

    void virtual b() {

        std::cout << "B--> b" << endl;
    }
};


typedef  void (*Pfunc) (void);

int main(void)
{
    B b;
    cout << "B is " <<sizeof(b) << endl;
    
    Pfunc pfc;
    for (int i = 0; i < 3; i++)
    {

        /*      (&b) Take the address of B 
            (int *)(&b) Convert the address of b to int type, so as to facilitate later access to the memory immediately following it
            *(int *)(&b)   Take out the contents in B (address of virtual function table)
            (int *) *(int *)(&b) The address of the virtual function table is converted to int type, which is convenient for later access to the memory immediately following it
            (int *) *(int *)(&b) + i  Using the address storage mechanism, + 1 automatically skips 4 (8) bytes, accesses the next memory content, and accesses the function address stored in the virtual function table
            (Pfunc)*   The function pointer address of virtual function table is converted to the function pointer address of pFunc type, which is convenient to call
                      pfc(); call
            

        */
        pfc = (Pfunc)*((int *) *(int *)(&b) + i);
        pfc();
    }




    cin.get();

    return 0;
}

Tags: C++ IE PHP snapshot Linux

Posted on Sun, 05 Jan 2020 14:53:04 -0800 by southofsomewhere