Citat:
Predrag Damnjanovic:
Imam jednu template klasu, sto nije mnogo ni bitno.
Jedna funkcija te klase bi trebala da kreira jedan novi objekat, te iste klase, ali sa drugim tipom (ovako : new ista_klasa<tip>;).
Problem je sto bi ja toj funkciji u run-time modu trebao nekako da prosledim tip koji zelim, dakle u trenutku kompajliranja se ne zna tip.
Da li je moguce to da se izvede?
Template upravo i sluzi da se sve ono sto se ne zna u compile-time-u prosledi kao parametar template-a.
Sam koncept template-a je mnogo flexibilniji nego sto izgleda na prvi pogled.
Naime, u okviru template koji ima proizvoljan broj parametara mozes imati jos funkcija/metoda koje su takodje parametrizovane svaka na svoj nacin.
Dalje, postavlja se pitanje kakva ova funkcija treba da bude. S obzirom da ti treba funkcija koja vraca/kreira objekte istog tipa kao sto je i klasa sama, u pitanju ti je neka <factory> funkcija. U klasicnom C++/class design-u, pozeljno je takve funkcije napraviti kao staticke metode. Medjutim, kod template-a ce ti "ubacivanje" takve funkcije u template klasu (proizvodjenje ove funkcije u metodu klase) samo praviti probleme - kasnije, u koriscenju te funkcije.
Primer:
template <typename T> class A
{
public:
template <typename U> static /*static moze, ali ne mora*/ A<U>& Create()
{
return *(new A<U>);
}
};
Kako sad pozivati metodu Create()?
Ako je metoda bila static, primer sa greskom:
A<int> a = A::Create<int>();
ovako bi bilo u
klasicnom, class-based C++-u. Medjutim, sa template-ima imas problem, jer ono A:: ne moze tek tako - mora i to A da bude navedeno sa nekim tipom kao parametrom, a taj tip ti uopste nije trebao u ovom slucaju, cak i ne igra nikakvu ulogu!
Dakle, mora da se "lupi" neki tip
Primer bez greske:
A<int> a = A<void>::Create<int>();
Dakle, imas onaj npr. void koji je tu tek zato da se template "raspertla".
Znaci, najbolje je da ti ova funkcija bude globalna funkcija, van klase:
template <typename T> class A
{
};
template <typename U> static /*static moze, ali ne mora*/ A<U>& Create()
{
return *(new A<U>);
}
E, ovo te vodi dalje u probleme Factory-ja: ako imas funkciju koja kreira objekte "spolja", sta ce ti onda public konstruktor za klasu A?
A ako stavis taj konstruktor da bude private/protected, onda treba da f-ju Create proglasis friend-om klase A.
Ni ovo ti nije lose.
A sta ako hoces da objekti klase A<neki_tip> mogu da kreiraju objekte klase A<neki_drugi_tip> ? Tada je Create metoda (ne-staticka) klase A, i sama klasa A postaje sama sebi factory klasa, sto ti je malo overkill za klasu A. Bolje da napravis posebnu klasu AFactory koja ce ti praviti objekte klase A<bilo_koji_tip>.
I tako dalje, i tako dalje, smorio sam.... ;)
Citat:
P.S. Imam resenje da fja samo vrati referencu pointera, pa ti sam kreiras novi objekat, kakav zelis, i dodelis ga pointeru. Ali me interesuje da li mora tako?
Ovaj P.S. bas i nisam razumeo, mene bi takvo resenje bolelo...