-
July 8th, 2014, 07:52 AM
#1
How can I create a template method in a C++ class?
Code:
class A {
public:
template<class T>
ObjectsBase* createObject(T* objType, Ogre::String name, Ogre::Vector3 position);
};
template<class T>
ObjectBase* A::createObject(T* objType, Ogre::String name, Ogre::Vector3 position);
My goal is to create any ObjectBase* derived object and return it to class A....
Any ideas?
Thanks
Jack
-
July 8th, 2014, 08:20 AM
#2
Re: How can I create a template method in a C++ class?
you need to define the 'body' of the templated memberfunction in a public header.
so you either add that code inline in the class definition
Code:
class A {
public:
template<class T>
ObjectsBase* createObject(T* objType, Ogre::String name, Ogre::Vector3 position)// No ; here
{
// Add implementation here
}
};
or you add the implementation outside of the class definition (but still in a header)
Code:
template<>
ObjectBase* A::createObject<class T>(T* objType, Ogre::String name, Ogre::Vector3 position)
{
// Add implementation here
}
As above, it's a general implementaiton
You can specialise by replacing <class T> by <class MyClass> and implement the function specific for a MyClass. This is handy if you can't generalize it for every possible template parameter.
In the case of a specialization, if so desired, you can define the prototype in a header, and implement in a .cpp.
Last edited by OReubens; July 8th, 2014 at 08:23 AM.
-
July 8th, 2014, 11:53 AM
#3
Re: How can I create a template method in a C++ class?
Apart from what OReubens suggested, I recommend not to return a raw pointer to the object, but a smart pointer. This relieves the caller of createObject from the question of the ownership of the object pointed to.
-
July 8th, 2014, 10:52 PM
#4
Re: How can I create a template method in a C++ class?
Thanks OReubens and Richard,
It works as expected now.
Code:
template<class T>
ObjectBase* createObject(T* objType, Ogre::String name, Ogre::Vector3 position) {
if(mDetourCrowd[name.c_str()]->getNbAgents() >= mDetourCrowd[name.c_str()]->getMaxNbAgents()) {
Ogre::LogManager::getSingletonPtr()->logMessage("Error: Cannot create crowd agent for new Object. Limit of "+Ogre::StringConverter::toString(mDetourCrowd[name.c_str()]->getMaxNbAgents())+" reached", Ogre::LML_CRITICAL);
throw new Ogre::Exception(1, "Cannot create crowd agent for new Object. Limit of "+Ogre::StringConverter::toString(mDetourCrowd[name.c_str()]->getMaxNbAgents())+" reached", "OgreRecastApplication::createObject("+name+")");
}
ObjectBase* obj = new T(name, mSceneMgr, mDetourCrowd[name.c_str()], mDebugDraw, position);
mObjects[name.c_str()] = obj;
return obj;
}
Do I call this method this way?
Code:
obj = createObject(new Worker(), "name", Ogre::Vector3(0,0,0))
Jack
Last edited by lucky6969b; July 9th, 2014 at 12:10 AM.
-
July 9th, 2014, 12:34 AM
#5
Re: How can I create a template method in a C++ class?
Originally Posted by lucky6969b
Thanks OReubens and Richard,
Code:
obj = createObject(new Worker(), "name", Ogre::Vector3(0,0,0))
This leaves you with a memory leak. The new Worker object is a temporary object you can never delete. Since you are not using it anyway, your method could be defined like this
Code:
template<class T>
std::shared_ptr<ObjectBase> createObject(Ogre::String name, Ogre::Vector3 position)
{
std::shared_ptr<ObjectBase> obj( new T(name, mSceneMgr, mDetourCrowd[name.c_str()], mDebugDraw, position));
mObjects[name.c_str()] = *obj;
return obj;
}
-
July 9th, 2014, 01:15 AM
#6
Re: How can I create a template method in a C++ class?
Thanks, Richard.
Code Updated.
Jack
-
July 9th, 2014, 02:51 AM
#7
Re: How can I create a template method in a C++ class?
Look how much easier to read your code becomes with a few local variables. You should really stop copy-pasting source code; it's a very bad habit.
Code:
template<class T>
ObjectBase* createObject(Ogre::String name, Ogre::Vector3 position)
{
auto detour = mDetourCrowd[name.c_str()];
if (detour->getNbAgents() >= detour->getMaxNbAgents()) {
const auto msg = "Cannot create crowd agent for new Object. Limit of "
+ Ogre::StringConverter::toString(detour->getMaxNbAgents())
+ " reached";
Ogre::LogManager::getSingletonPtr()->logMessage("Error: " + msg, Ogre::LML_CRITICAL);
throw new Ogre::Exception(1, msg, "OgreRecastApplication::createObject(" + name + ")");
}
ObjectBase* obj = new T(name, mSceneMgr, detour, mDebugDraw, position);
mObjects[name.c_str()] = obj;
return obj;
}
Also, it's best to throw exceptions by value and catch them by const reference. So unless you are working within a framework that requires throwing dynamically allocated exceptions, I would change that.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|