1. 程式人生 > >【c++】用工廠模式實現計算器功能(附工廠模式程式碼)

【c++】用工廠模式實現計算器功能(附工廠模式程式碼)

工廠模式

編譯環境:Linux vim

DynBase.h

#ifndef _DYN_BASE_H_
#define _DYN_BASE_H_

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

typedef void* (*CREATE_FUNC)();

class DynObjectFactory
{
public:
	static void* CreateObject(const string& name)
	{
		map<string, CREATE_FUNC>::const_iterator it;
		it = mapCls_.find(name);
		if (it == mapCls_.end())
			return 0;
		else
			return it->second();

	}

	static void Register(const string& name, CREATE_FUNC func)
	{
		mapCls_[name] = func;
	}
private:
	static map<string, CREATE_FUNC> mapCls_;
};

// g++ 
__attribute ((weak)) map<string, CREATE_FUNC> DynObjectFactory::mapCls_;

class Register
{
public:
	Register(const string& name, CREATE_FUNC func)
	{
		DynObjectFactory::Register(name, func);
	}
};

#define REGISTER_CLASS(class_name) \
class class_name##Register { \
public: \
	static void* NewInstance() \
	{ \
		return new class_name; \
	} \
private: \
	static Register reg_; \
}; \
Register class_name##Register::reg_(#class_name, class_name##Register::NewInstance)


#endif // _DYN_BASE_H_

Calculate.h
/*
**************************************************************************
* File Name: Calculate.cpp
* Function : 1) 
*            2) 
* Author   : 
* Created Time: 2017年02月16日 星期四 15時42分40秒
**************************************************************************
*/

#ifndef _CALCULATE_H_
#define _CALCULATE_H_

#include <string>

using namespace std;

class Cal
{
public:
    static double numA_;
    static double numB_;

    virtual void calOption() = 0;
    virtual ~Cal() {}
};


class Plus: public Cal
{
public:
    void calOption();
//    ~Plus();
};

class Sub: public Cal
{
public:
    void calOption();
  //  ~Sub();
};

class Mul: public Cal
{
public:
    void calOption();
  //  ~Mul();
};

class Div: public Cal
{
public:
    void calOption();
  //  ~Div();
};

#endif

Calculate.cpp
/*
**************************************************************************
* File Name: Calculate.cpp
* Function : 1) 
*            2) 
* Author   : 
* Created Time: 2017年02月16日 星期四 15時53分14秒
**************************************************************************
*/

#include <iostream>
#include <string>
#include <string.h>
#include <stdlib.h>
#include "Calculate.h"
#include "DynBase.h"
//#include "DynObjectFactory.h"

using namespace std;

double Cal::numA_ = 0;
double Cal::numB_ = 0;

void Plus::calOption()
{
    double result = Cal::numA_ + Cal::numB_;

    cout << Cal::numA_ << " + " << Cal::numB_ << " = " << result << endl;
}

void Sub::calOption()
{
    double result = Cal::numA_ - Cal::numB_;

    cout << Cal::numA_ << " - " << Cal::numB_ << " = " << result << endl;
}

void Mul::calOption()
{
    double result = Cal::numA_ * Cal::numB_;

    cout << Cal::numA_ << " x " << Cal::numB_ << " = " << result << endl;
}

void Div::calOption()
{
    double result = Cal::numA_ / Cal::numB_;

    cout << Cal::numA_ << " / " << Cal::numB_ << " = " << result << endl;
}

REGISTER_CLASS(Plus);
REGISTER_CLASS(Sub);
REGISTER_CLASS(Mul);
REGISTER_CLASS(Div);
Main.cpp
/*
**************************************************************************
* File Name: Main.cpp
* Function : 1) 
*            2) 
* Author   : 
* Created Time: 2017年02月16日 星期四 15時40分29秒
**************************************************************************
*/

#include <iostream>
#include <string>
#include <stdlib.h>
#include <vector>
#include "Calculate.h"
//#include "DynObjectFactory.h"
#include "DynBase.h"

using namespace std;

int main()
{
    vector<Cal*> v;
    vector<Cal*>::const_iterator it;

    Cal* ps;

    string option;

    while(1)
    {
        system("clear");
        cout << "Calculator" << endl; 
        cout << "Please input a number:" << endl;
        cin >> Cal::numA_;
        cout << "Please input operation (Plus/Sub/Mul/Div)" << endl;
        cin >> option;
        cout << "Please input another number:" << endl;
        cin >> Cal::numB_;
        system("clear");

        ps = static_cast<Cal*>(DynObjectFactory::CreateObject(option));
        v.push_back(ps);
        it = v.begin();
        (*it)->calOption();
        delete(*it);

        cin.get();
        cin.get();
    }

    return 0;
}