Factory Pattern - Linker Error



  • Hi

    Ich hab mal nen neuen Thread aufgemacht, weil ich Probleme hab, ne Factory Methode in C++ zu implementieren. Ist sicher nur ein blöder Fehler, aber ich finde ihn nicht. Wäre daher froh über jede Hilfe.

    Also hier mein Code:
    Product.h

    #pragma once
    
    class Product
    {
    public:
    	Product(void){}
    	virtual ~Product(void) = 0;
    	virtual void say_hello() = 0;
    };
    

    Creator.h

    #pragma once
    
    class Product;
    
    class Creator
    {
    public:
    	Creator(void) {}
    	virtual ~Creator(void) = 0;
    	virtual Product* create() = 0;
    };
    

    Concrete_Product.h und .cpp

    #pragma once
    
    #include "Product.h"
    
    class Concrete_Product :
    	public Product
    {
    public:
    	Concrete_Product(void);
    	~Concrete_Product(void);
    	virtual void say_hello();
    };
    //.cpp
    #include "Concrete_Product.h"
    #include <iostream>
    
    Concrete_Product::Concrete_Product(void)
    {
    }
    
    Concrete_Product::~Concrete_Product(void)
    {
    }
    
    void Concrete_Product::say_hello()
    {
    	std::cout << "Hello from Concrete Product" << std::endl;
    }
    

    Concrete_Creator.h und .cpp

    #pragma once
    
    #include "Creator.h"
    
    class Product;
    
    class Concrete_Creator :
    	public Creator
    {
    public:
    	Concrete_Creator(void);
    	~Concrete_Creator(void);
    	virtual Product* create();
    
    };
    //.cpp
    #include "Concrete_Creator.h"
    #include "Product.h"
    #include "Concrete_Product.h"
    
    Concrete_Creator::Concrete_Creator(void)
    {
    }
    
    Concrete_Creator::~Concrete_Creator(void)
    {
    }
    
    Product* Concrete_Creator::create() 
    {
    	return new Concrete_Product();
    }
    

    Main.cpp

    #include <iostream>
    #include "Creator.h"
    #include "Product.h"
    #include "Concrete_Creator.h"
    #include "Concrete_Product.h"
    
    using namespace std;
    
    int main()
    {
    	Creator* creatorA;
    	creatorA = new Concrete_Creator;
    	Product* productA;
    	productA = creatorA->create();
    	productA->say_hello();
    	return 0;
    }
    

    Fehlermeldung:

    Concrete_Creator.obj : error LNK2019: 
    unresolved external symbol "public: virtual __thiscall Creator::~Creator(void)" (??1Creator@@UAE@XZ) 
    referenced in function "public: virtual __thiscall Concrete_Creator::~Concrete_Creator(void)" (??1Concrete_Creator@@UAE@XZ)
    Concrete_Product.obj : error LNK2019: 
    unresolved external symbol "public: virtual __thiscall Product::~Product(void)" (??1Product@@UAE@XZ) 
    referenced in function "public: virtual __thiscall Concrete_Product::~Concrete_Product(void)" (??1Concrete_Product@@UAE@XZ)
    

    Any ideas?

    Danke schonmal



  • ps: bin von dem Beispiel von der Seite unten ausgegangen.
    Obwohl das C# ist, aber ich glaube ich habs richtig umgesetzt..
    http://www.dofactory.com/Patterns/PatternFactory.aspx#_self2



  • Dir fehlen die Implementierungen der Destruktoren von Product und Creator.



  • *doh*

    Danke, das wars 👍
    Ein {} am Ende der Zeile hats gebraucht.
    Ich hab überall anders gesucht, aber nicht da. Würd ich mal unter meine blödsten Pannen beim Programmieren einordnen.



  • Hmm..

    Product* Concrete_Creator::create() 
    {
        return new Concrete_Product();
    }
    

    Kann man in C++ das eigentlich nicht anders lösen, als dass man in der create() Methode der Creaters einen Zeiger auf ein Produkt zurückgibt?
    Ich glaube, dass das ärger geben könnte beim aufräumen.



  • Nö, ein polymorphes Objekt "weiss" auch von einem Basisklassenzeiger, welcher Destruktor der konkreteste ist und arbeitet diesen zuerst ab.



  • Hmm
    das meint ich nicht. Probleme könnten auftreten, weil die Funktion ein Objekt erstellt, dass man dann ausserhalb löschen muss:

    Creator* creatorA = new Concrete_Creator();
        Product* productA;
        product = creatorA->create(); // Gibt pointer auf Product zurück
        product->say_hello();
        delete productA;  // Darf ich dann nicht vergessen
        delete creatorA;
    

    Wäre da eventuell ein auto_ptr nützlich?

    Danke schonmal



  • boost::shared_ptr



  • .a schrieb:

    boost::shared_ptr

    Für den oben genannten Zweck wäre ein std::auto_ptr<> die bessere Wahl, weil für den Zweck ein boost::shared_ptr<> zuviel overhead hätte.

    BR
    Vinzenz


Anmelden zum Antworten