jeudi 9 avril 2020

How to store the objects of different classes in a map while implementing Factory Design Pattern in C++?

I tried to implement Factory Design pattern for an address validation example in C++.

I wanted to create a Factory class for various validator classes. And with the help of runtime polymorphism, I thought I can store and return pointers of base classes using unordered_map. But I'm getting weird errors during compilation.

Am I implementing it wrong? or Is it not posibble in C++ to store the polymorphic object pointers in a container?

This is the implementation.

#include <bits/stdc++.h>
using namespace std;


class Address{
    string number;
    string street;
    string city;
    string country;

    public:
        Address(string _number,string _street, string _city, string _country){
            number = _number;
            street = _street;
            city = _city;
            country = _country;
        }

        string getCountry(){
            return country;
        }
};

class AddressValidator{
    public:
        virtual bool Validate(Address&) = 0;
};

class INValidator : public AddressValidator{
    public:
        bool Validate(Address& add){
            cout<<"INDIA Validated!"<<endl;
            return true;
        }
};

class USValidator : public AddressValidator{
    public:
        bool Validate(Address& add){
            cout<<"US Validated!"<<endl;
            return true;
        }
};

class UKValidator : public AddressValidator{
    public:
        bool Validate(Address& add){
            cout<<"UK Validated!"<<endl;
            return true;
        }
};

class AddressValidatorFactory{
    private:
        static AddressValidatorFactory* valids;
        static unordered_map<string, AddressValidator*> validators;
        AddressValidatorFactory(){
            validators["IN"] = new INValidator();
            validators["UK"] = new UKValidator();
            validators["US"] = new USValidator();
        }
    public:
        static AddressValidatorFactory* getInstance(){
            if(valids==NULL)
                valids = new AddressValidatorFactory;
            return valids;
        }

        static AddressValidator* getValidator(string cnt){
            if(validators.find(cnt)==validators.end())
                throw "Validator for the country not available.";
            return validators[cnt];
        }

};

AddressValidatorFactory* AddressValidatorFactory::valids = NULL;

int main(void){
    Address user1("12345","Cyberbad","Hyd", "IN");

    auto tmp = AddressValidatorFactory::getInstance();
    auto inv = tmp->getValidator(user1.getCountry());
    inv->Validate(user1);
}

This is the error I was facing.

/tmp/ccCOj3KS.o: In function `AddressValidatorFactory::AddressValidatorFactory()':
factory.cpp:(.text._ZN23AddressValidatorFactoryC2Ev[_ZN23AddressValidatorFactoryC5Ev]+0x65): undefined reference to `AddressValidatorFactory::validators[abi:cxx11]'
factory.cpp:(.text._ZN23AddressValidatorFactoryC2Ev[_ZN23AddressValidatorFactoryC5Ev]+0xd2): undefined reference to `AddressValidatorFactory::validators[abi:cxx11]'
factory.cpp:(.text._ZN23AddressValidatorFactoryC2Ev[_ZN23AddressValidatorFactoryC5Ev]+0x13f): undefined reference to `AddressValidatorFactory::validators[abi:cxx11]'
/tmp/ccCOj3KS.o: In function `AddressValidatorFactory::getValidator(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)':
factory.cpp:(.text._ZN23AddressValidatorFactory12getValidatorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN23AddressValidatorFactory12getValidatorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x1e): undefined reference to `AddressValidatorFactory::validators[abi:cxx11]'
factory.cpp:(.text._ZN23AddressValidatorFactory12getValidatorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN23AddressValidatorFactory12getValidatorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x35): undefined reference to `AddressValidatorFactory::validators[abi:cxx11]'
/tmp/ccCOj3KS.o:factory.cpp:(.text._ZN23AddressValidatorFactory12getValidatorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN23AddressValidatorFactory12getValidatorENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x8b): more undefined references to `AddressValidatorFactory::validators[abi:cxx11]' follow
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'factory' failed
make: *** [factory] Error 1

Aucun commentaire:

Enregistrer un commentaire