c++でStrategyパターンってこんな感じ? constを意識してみる。

#include <iostream>
#include <string>
#include <map>
#include <stdexcept>
#include <exception>
#include "openssl/md5.h"
#include "openssl/sha.h"

typedef unsigned int u_int;

using std::cout;
using std::cerr;
using std::endl;
using std::string;
using std::logic_error;

struct HashPtn
{struct SHA1_hash : public HashPtn 
{   
    // const1 引数を変更しないconst
    // const2 この関数を使うことによってオブジェクトに何の変更も起きないことを指定するconst
    virtual string get_hash ( const string s ) const 
    {
        unsigned char digest[SHA_DIGEST_LENGTH];
        SHA_CTX ctx;

        SHA1_Init(&ctx);
        SHA1_Update(&ctx, reinterpret_cast<const unsigned char *>(s.c_str()), s.length());
        SHA1_Final(digest, &ctx);

        string ret = reinterpret_cast<char *>(digest);
        return ret;
    }
};

struct Hash
{
    HashPtn * m_strategy ;
    Hash( HashPtn * in_strategy )
    {
        m_strategy = in_strategy ;
    }

    string get_hash_( string s ) const 
    {
        return m_strategy->get_hash( s );
    }
} ;

Hash get_algorithms_map( const string my_algorithm )
{   
    typedef map<string, Hash> algorithms_map_t;
    algorithms_map_t algorithms_map;
    
    MD5_hash md5;
    SHA1_hash sha1;
    Hash md5_h( &md5 );
    Hash sha1_h( &sha1 );

    algorithms_map.insert( pair <string, Hash>( "md5" , md5_h  ) );
    algorithms_map.insert( pair <string, Hash>( "sha1", sha1_h ) );
    
    algorithms_map_t::iterator p;
    p = algorithms_map.find( my_algorithm );
    if ( p != algorithms_map.end())
    {
        return (*p).second;
    }   
    else 
    {
        throw logic_error("not found");
    }
}

    
int main ()
{   
    // 本当は引数とかでこの値を入れると思います。
    string my_algorithm = "md5";
    Hash h = get_algorithms_map( my_algorithm );                                                      
    cerr << h.get_hash_("hoge") << endl;
    return 0;
} 

    virtual string get_hash( const string s ) const = 0;
};  
    
struct MD5_hash : public HashPtn 
{   
    virtual string get_hash ( const string s ) const 
    {
        unsigned char digest[MD5_DIGEST_LENGTH];
        MD5_CTX ctx;
        MD5_Init(&ctx);
        MD5_Update(&ctx, reinterpret_cast<const unsigned char *>(s.c_str()), s.length());
        MD5_Final(digest, &ctx);

        string ret = reinterpret_cast<char *>(digest);
        return ret;
    }
};