Problem when using a singleton with an abstract factory

0

I only put the title of the pattern that I am using, but that is not a problem (maybe it seems to me to be a header problem) I also try to detail everything in my code with its respective compilation error. If someone has any idea to solve it, I would appreciate it for the help.

#ifndef SUPERMARKET_SUPERMARKET_H_
#define SUPERMARKET_SUPERMARKET_H_

#include "CountryFactory.h"

class Supermarket {
private:
    Menu *menu;
    Ticket *ticket;
public:
    Supermarket();
    void vender();
    virtual ~Supermarket();
};

#endif

#include "Supermarket.h"

Supermarket::Supermarket() {
    ticket = CountryFactory::getInstance()->createTicket();
    menu = CountryFactory::getInstance()->createMenu();
}

void Supermarket::vender() {
    bool terminado = false;

    do {
        menu->execute(ticket);
    }while (!terminado);
}

Supermarket::~Supermarket() {
    delete ticket;
    delete menu;
}

Applying abstract Factory with singleton

#ifndef SUPERMARKET_COUNTRYFACTORY_H_
#define SUPERMARKET_COUNTRYFACTORY_H_

#include "Menu.h"
#include "Ticket.h"

class CountryFactory {
protected:
    CountryFactory();
    static CountryFactory* instance;
public:
    static CountryFactory* getInstance();
    virtual Menu* createMenu();
    virtual Ticket* createTicket();
    virtual ~CountryFactory();
};

#endif

Here I do not know how to eliminate a singleton with the destroyer without giving me an infinite loop

#include "CountryFactory.h"
#include "SpanishFactory.h"


CountryFactory* CountryFactory::instance = nullptr;

CountryFactory::CountryFactory() {
}

CountryFactory* CountryFactory::getInstance() {
    if(instance){
        instance = new SpanishFactory();
    }
    return instance;
}

CountryFactory::~CountryFactory() {
}

This is where I get the problem, which I think is a header issue.

#ifndef SUPERMARKET_COUNTRYFACTORY_H_
#define SUPERMARKET_COUNTRYFACTORY_H_

#include "CountryFactory.h"

class SpanishFactory : public CountryFactory{
public:
    explicit SpanishFactory();
    Menu* createMenu() override;
    Ticket* createTicket() override;
    virtual ~SpanishFactory();
};

#endif

member declaration not found (in each)

SpanishFactory::SpanishFactory() : CountryFactory() {
}

Menu* SpanishFactory::createMenu() {
    return new Menu();
}

Ticket* SpanishFactory::createTicket() {
    return new Ticket();
}

SpanishFactory::~SpanishFactory() {
}

Error type when compiling:

20:49:16 **** Incremental Build of configuration Debug for project supermarket ****
make all 
Building file: ../src/supermarket/CountryFactory.cpp
Invoking: GCC C++ Compiler
g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/supermarket/CountryFactory.d" -MT"src/supermarket/CountryFactory.o" -o "src/supermarket/CountryFactory.o" "../src/supermarket/CountryFactory.cpp"
../src/supermarket/CountryFactory.cpp: In static member function ‘static CountryFactory* CountryFactory::getInstance()’:
../src/supermarket/CountryFactory.cpp:12:18: error: expected type-specifier before ‘SpanishFactory’
   instance = new SpanishFactory();
                  ^~~~~~~~~~~~~~
make: *** [src/supermarket/CountryFactory.o] Error 1
src/supermarket/subdir.mk:33: recipe for target 'src/supermarket/CountryFactory.o' failed

20:49:17 Build Finished (took 637ms)
    
asked by neoprox 01.11.2018 в 01:00
source

1 answer

1

As indicated in the comments, you are using the same guard in two different headers. This makes the compiler not load the header of SpanishFactory and therefore is not able to find the manufacturer of that factory.

Modify the guards to be different:

#ifndef SUPERMARKET_SPANISHFACTORY_H_
//                  ~~~~~~~

#define SUPERMARKET_SPANISHFACTORY_H_
//                  ~~~~~~~

#include "CountryFactory.h"

class SpanishFactory : public CountryFactory{

// ...
    
answered by 02.11.2018 в 23:58