Immutable


読み取りしかしないなら排他制御を行う必要がない、というパターン。


以下は増補改訂版 Java言語で学ぶデザインパターン入門 マルチスレッド編のサンプルを Boost.Thread を使って書いたコード。


person.h

#ifndef MTDP_IMMUTABLE_PERSON_H_INCLUDED
#define MTDP_IMMUTABLE_PERSON_H_INCLUDED

namespace mtdp{ namespace immutable
{

class person
{
private:
    // immutable であることを強調するために const にする
    const std::string name_;
    const std::string address_;

public:
    person(std::string name, std::string address)
        : name_(name), address_(address)
    {
    }

    // 各メソッドは全て const である必要がある。
    std::string name() const
    {
        return name_;
    }
    std::string address() const
    {
        return address_;
    }
    std::string to_string() const
    {
        return "[ Person: name = " + name_ + ", address = " + address_ + " ]";
    }
};

}}

#endif // MTDP_IMMUTABLE_PERSON_H_INCLUDED

main.cpp

#include <boost/thread.hpp>
#include <boost/bind.hpp>
#include "person.h"
#include "print_person_thread.h"

namespace mtdp{ namespace immutable
{
    void main()
    {
        boost::shared_ptr<person> alice(new person("Alice", "Alaska"));

        boost::thread_group group;
        group.create_thread(boost::bind(&print_person_thread::run, boost::shared_ptr<print_person_thread>(new print_person_thread(alice))));
        group.create_thread(boost::bind(&print_person_thread::run, boost::shared_ptr<print_person_thread>(new print_person_thread(alice))));
        group.create_thread(boost::bind(&print_person_thread::run, boost::shared_ptr<print_person_thread>(new print_person_thread(alice))));
        group.join_all();
    }
}}

print_person_thread.h

#ifndef MTDP_IMMUTABLE_PRINT_PERSON_THREAD_H_INCLUDED
#define MTDP_IMMUTABLE_PRINT_PERSON_THREAD_H_INCLUDED

#include <boost/shared_ptr.hpp>
#include <iostream>
#include "person.h"
#include "../thread_helper.h"

// for ::GetCurrentThreadId
#include <windows.h>

namespace mtdp{ namespace immutable
{

class print_person_thread
{
private:
    boost::shared_ptr<person> person_;

public:
    print_person_thread(boost::shared_ptr<person> p) : person_(p)
    {
    }

    void run()
    {
        while (true)
        {
            thread_helper::shared_cout("Thread-" + to_string(::GetCurrentThreadId()) + " prints " + person_->to_string() + "\n");
        }
    }
};

}}

#endif // MTDP_IMMUTABLE_PRINT_PERSON_THREAD_H_INCLUDED