Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #9245

Re: Mapping operations to codes

From Victor Bazarov <v.bazarov@comcast.invalid>
Newsgroups comp.lang.c++
Subject Re: Mapping operations to codes
Date 2011-08-23 13:51 -0400
Organization A noiseless patient Spider
Message-ID <j30pb0$1pi$1@dont-email.me> (permalink)
References <9bi243F224U1@mid.individual.net>

Show all headers | View raw


On 8/23/2011 12:17 PM, Default User wrote:
> I'm not sure how well that subject captured the topic. Anyway, this is a
> branching from my previous topic "Fun with member-function pointers".
>
> The general problem is that we have a number of  "drivers" for instruments.
> These are essentially an abstraction layer than translates control messages
> from higher-level modules into something the particular hardware can
> understand. The API for this is a system of operation codes and an
> associated data word that has bits set or cleared for various options.
>
> My current solution is to map the op codes to pointers to member functions
> that handle the particular operation. There's also a requirement that each
> driver be able to respond with a list of the supported op codes. The problem
> is that it results in a lot of very similar code in each driver. I had
> wanted to push down as much behavior as possible to the base class. My
> initial thoughts (see other thread) look like they result in undefined
> behavior, so no good.

The maps don't seem to be needed per instance of class ('test') but 
rather per class (i.e. they should probably be static).  That's all I 
have so far.  I would probably try rewriting the code so that 'write' 
and 'list' functions were static as well.

Currently there seems to be no need in using the 'this' to call the H0 
or H4 members - you're not using any instance specific data here. 
Hence, there is no need for H0 or H4 to be non-static either.  Hence 
your "pointer to member" statement is unsubstantiated.  Each "method" 
for dealing with "code" could just as well be static...

Please supply a more complete design that would prove the need to use 
non-static driving methods.

It would be nice to see the need for more than one 'test'.  Perhaps the 
'main' should define two different "drivers" (or even two instances of 
each of the two different "drivers") to demonstrate the need for keeping 
the maps of members in the instance, and not per class.  So far even if 
you are trying to use non-static data in those H0 and H4 member 
functions, the *map* still doesn't have to be per instance.

>
> Below is a small representation of the problem. It's not the real code
> (which would be very large), so it's not necessary to suggest improvements
> in layout or that sort of thing. Thoughts on attacking the general problem
> would be welcome.
>
>
> Brian
>
>
> ================= code =================
>
> #include<iostream>
> #include<map>
> #define CALL_HANDLER(object,ptrToMember)((object).*(ptrToMember))
>
> class tbase
> {
> public:
>
> protected:
>     tbase()
>     {
>     }
>     virtual ~tbase()
>     {
>     }
> };
>
> class test : public tbase
> {
> public:
>     typedef int (test::*HandlerPtr)(int);
>
>     test() // sets up the map of handlers to op codes
>     {
>        handlers[0] =&test::H0;
>        handlers[4] =&test::H4;
>     }
>     virtual ~tbase()
>     {
>     }
>     virtual int H0(int data)
>     {
>        std::cout<<  "test::H0: "<<  data<<  "\n";
>        return data;
>     }
>     int H4(int data)
>     {
>        std::cout<<  "test::H4: "<<  data<<  "\n";
>        return data;
>     }

Not sure how it plays into your goals, so is there a reason why one is 
virtual and the other isn't?

>     void write(int data, int code) // finds the handler and passes data
>     {
>        std::map<int, HandlerPtr>::iterator it;
>        it = handlers.find(code);
>        if (it != handlers.end())
>        {
>           // Found, call the function pointer
>           CALL_HANDLER(*this, it->second)(data);
>        }
>        else // unhandled code
>        {
>           // error handling
>        }
>     }
>     void list() // just prints supported op codes
>     {
>        std::map<int, HandlerPtr>::iterator it = handlers.begin();
>
>        std::cout<<  "Supported Op codes:\n";
>        while (it != handlers.end())
>        {
>           std::cout<<  it->first<<  "\n";
>           it++;
>        }
>     }
> private:
>     std::map<int, HandlerPtr>  handlers;
> };
>
> int main()
> {
>     test t;
>     t.list();
>     t.write(123, 0);
>     t.write(456, 4);
>     return 0;
> }
>
>

V
-- 
I do not respond to top-posted replies, please don't ask

Back to comp.lang.c++ | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Mapping operations to codes "Default User" <defaultuserbr@yahoo.com> - 2011-08-23 11:17 -0500
  Re: Mapping operations to codes Paul <pchristor@yahoo.co.uk> - 2011-08-23 10:33 -0700
  Re: Mapping operations to codes Victor Bazarov <v.bazarov@comcast.invalid> - 2011-08-23 13:51 -0400
    Re: Mapping operations to codes "Default User" <defaultuserbr@yahoo.com> - 2011-08-23 14:30 -0500
      Re: Mapping operations to codes Victor Bazarov <v.bazarov@comcast.invalid> - 2011-08-23 16:23 -0400
        Re: Mapping operations to codes "Default User" <defaultuserbr@yahoo.com> - 2011-08-23 16:01 -0500
          Re: Mapping operations to codes Victor Bazarov <v.bazarov@comcast.invalid> - 2011-08-23 17:42 -0400
            Re: Mapping operations to codes "Default User" <defaultuserbr@yahoo.com> - 2011-08-23 17:05 -0500
              Re: Mapping operations to codes Paul <pchristor@yahoo.co.uk> - 2011-08-24 03:23 -0700

csiph-web