Search code examples
c++oopinterfacefactory-patternmulti-tier

How to implement Factory pattern?


I am trying to implement factory class and interface. But i am getting the below error message. I have created a factory class which decides which class to return NormalTaxManager or ImportedTaxManager. I have provided the abstraction using interface.

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

class TaxInterface
{
public:
    virtual int calculate_tax(int price,int quantity)=0;
};

class TaxFactory
{
public:
    // Factory Method
    static TaxInterface *callManager(int imported)
    {
        if (imported == 0)
            return new NormalTaxManager;
        else
            return new ImportedTaxManager;
    }
};

class NormalTaxManager: public TaxInterface
{
public:
    virtual int calculate_tax(int price,int quantity)
    {
        cout << "NormalTaxManager\n";
        price=quantity*price*10/100;
        return price;
    }
};

class ImportedTaxManager: public TaxInterface
{
public:
    virtual int calculate_tax(int price,int quantity)
    {
        cout << "ImportedTaxManager\n";
        price=quantity*price*5/100;
        return price;
    }
};

int main()
{
    TaxFactory f;
    TaxInterface *a = f.callManager(1);
    a->calculate_tax(100,2);
    //    int price=TaxInterface::callManager(1)->calculate_tax(100,2);
}

Problem:

 error: ‘NormalTaxManager’ does not name a type
 error: ‘ImportedTaxManager’ does not name a type

Solution

  • You need to declare NormalTaxManager and ImportedTaxManager before TaxInterface.

    And you also need to do the reverse.

    In order to fix that (classical) C++ circular reference problem, you need to split your code between .cpp and .h files

    Put TaxInterface that is abstract and has no implementation in a file of its own : TaxInterface.h.

    For example, split ImportedTaxManager in two files :

    .h

    #pragma once
    #include "taxinterface.h"
    
    class ImportedTaxManager : public TaxInterface
    {
    public:
        virtual int calculate_tax(int price, int quantity);
    };
    

    .cpp

    #include "stdafx.h"
    #include<iostream>
    using namespace std; 
    
    #include "ImportedTaxManager.h"
    
    int ImportedTaxManager::calculate_tax(int price, int quantity)
    {
        cout << "ImportedTaxManager\n";
        price = quantity*price * 5 / 100;
        return price;
    }
    

    If you re "clever" you can "save" some files.

    But it is more easy to maintain code that is split between headers (.h) and implementation (.cpp).

    Because C++ needs declarations of everything that is used, you often get circular references that can be solved by spliting between .h and .cpp

    Full working solution : http://1drv.ms/1Pe25SQ

    Regards