[C++] Template factory + inheritance

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
Hallo,

Ik zou het volgende willen doen in C++:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
class GenericFactory
{
public:
    template <typename T>
    virtual Something<T>* createInstance() = 0;
}

class SpecificFactory : public GenericFactory 
{
public:
    template <typename T>
    Something<T>* createInstance();
}


Dan wil ik ergens het volgende doen:
code:
1
2
3
void method(GenericFactory *fac) {
    Something<EenKlasse> *ptr = fac->createInstance<EenKlasse>();
}


En afhankelijk van het subtype van GenericFactory worden dan andere Something objecten gecreëerd.
Helaas is dit een fictief voorbeeld, aangezien templating en inheritance niet zo goed samengaan...

Ik vroeg me echter af hoe je iets soortgelijks best kan doen?
Ik wil dus eigenlijk een interface over een factory die templated objecten kan aanleveren.

In mijn situatie kan ik hier nu wel omheen werken, maar hoe kun je dit elegant oplossen?

Voor de duidelijkheid, dezelfde situatie zonder templating zou er als volgt uitzien:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class GenericFactory
{
public:
    virtual Something *createInstance() = 0;
}

class SpecificFactory
{
public:
    Something *createInstance();
}

void method(GenericFactory *fac)
{
    Something *ptr = fac->createInstance();
    // Hier is GenericFactory bvb. eigenlijk een SpecificFactory,
    // en levert deze methode dan ook een Specific implementatie van Something.
}

Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

volgens mij kan je geen virtuele template functies hebben in C++, maar je kan wel een templated factory hebben
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
template<typename T>
class factory
{
public:
  virtual something<T> *createinstance() = 0;
};

class foo
{
  //een stel abstracte functies
};

class specific_foo : public something<foo>
{
  //implementatie van abstracte functies
};

class foo_factory : public factory<foo>
{
public:
  something<foo> *createinstance() { return new specific_foo(); }
};

ik weet niet in hoeverre dat je gaat helpen, maar je kan geen "generic" factory hebben die "alle" types kan maken (wat je template natuurlijk inhoud)

een andere oplossing is om iets te doen als dit (losse hand code, moet je nog ff fixen waarschijnlijk)
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <typeinfo>

class genericfactory
{
public:
  virtual void *createinstancehelper(const std::type_info &info) = 0;

  template<typename T>
  inline something<T>* createinstance()
  {
    return dynamic_cast<something<T> *>(createinstancehelper(typeid(T)));
  }
};

class specificfactory : public genericfactory
{
public:
  void *createinstancehelper(const std::type_info &info)
  {
    if(info == typeid(foo)) return (void *)static_cast<something<foo> *>(new specificfoo()); //specificfoo inherits something<foo>
    else if(info == typeid(bar)) return (void *)static_cast<something<bar> *>(new specificbar());
    else return (void *)0; //of gooi een exception, wat jij wilt
  }
};

void main()
{
  genericfactory *fac = new specificfactory();
  something<foo> *obj1 = fac->createinstance<foo>();
  something<other_type> *obj2 = fac->createinstance<other_type>(); //obj2 = 0
}


maar hoe goed dit werkt (vooral cross-object) is nogal... compiler-afhankelijk, en vereist ook dat RTTI aan staat.

[ Voor 139% gewijzigd door MLM op 28-12-2010 17:52 . Reden: code op c++ gezet ]

-niks-


  • DieterVDW
  • Registratie: Juli 2002
  • Laatst online: 12-02-2017
MLM schreef op dinsdag 28 december 2010 @ 17:27:
maar hoe goed dit werkt (vooral cross-object) is nogal... compiler-afhankelijk, en vereist ook dat RTTI aan staat.
Bedankt! Daar had ik nog niet aan gedacht.
Interessante optie, helaas inderdaad wat omslachtig en weird.