Et anna boost::threadille parametreja Resource:n konstruktorissa. Tästä syystä boost::thread pitää usein varata dynaamisesti:
Code: Select all
boost::thread * m_thread = new boost:thread(funktio, parametrit);
Ajaa
funktion uudessa säikeessä. Ts. ei ole olemassa validia boost::thread instanssia, mikäli thread ei ole käynnissä. m_thread->join() käytännössä tuhoaa thread-olion, etkä voi käynnistää säijettä uudestaan samalla instanssilla.
Jos dynaaminen thread olio ei käy päinsä, pitää jäsenoliolle antaa parametrit kuten muillekkin Resource:n konstruktorissa:
Code: Select all
template <typename T>
ResourceManager<T>::Resource::Resource(T* resource, unsigned int uses)
: resource(resource), uses(uses), loader(loader_thread_main, parametri)
{
}
Koodivinkkinä sanoisin, että ota Resource-luokka ulos ResourceManager-luokasta. Käytä mieluummin namespace + friend yhdistelmää, jolloin Resource-luokka on ulkona ResourceManagerista ja näiden ylläpito helpottuu. (erityisesti implementaatio) Määritä siis Resource-malli ResourceManager-mallin kaveriksi, ja siirrä Resource-malli tarvittaessa detail-namespaceen, jos sen ei haluta näkyvän suoraan käyttäjälle. "luokan määritys luokan sisälle" on yleesä hyödyllinen silloin, kun tarvitaan POD tietotyyppi tyyliin "struct data { void * pdata; };" ja sen ei tarvitse näkyä luokan käyttäjille.
Templateista muistuttasin, että niitä ei voida implementoida kuten tavallisia luokkia, koska ne eivät ole luokkia, vaan malleja! Paras tuntemani tapa on esitellä malliluokka templateheader.hpp tiedostossa (kuten olet jo tehnytkin) ja
sisällyttää sitten templateimpl.inl-tiedosto templateheader.h:n lopussa. (templateheader.h headerguardien sisällä, templateimpl.inl ei tarvitse guardeja, samaan tapaan kuin .cpp. Kannattaa lisätä @note templateimpl.inl:een, että ko. tiedosto on jo sisällytetty toiseen headeriin mukaan, ettet mene sotkemaan esikääntäjän kanssa.)
C++11 helpottaa mallien implementaatiota sallimalla extern:n käytön template-luokille.