Hierarchies can currently only be registered for reference types, not for value types.
cast<class>
operator. asBEHAVE_IMPLICIT_REF_CAST should be used when you want to allow the compiler to implicitly perform the cast as necessary.Usually you'll want to use asBEHAVE_IMPLICIT_REF_CAST for casts from a derived type to the base type, and asBEHAVE_REF_CAST for casts from a base type to a derived type.
// Example REF_CAST behaviour template<class A, B> B* refCast(A* a) { // If the handle already is a null handle, then just return the null handle if( !a ) return 0; // Now try to dynamically cast the pointer to the wanted type B* b = dynamic_cast<B*>(a); if( b == 0 ) { // Since the cast couldn't be made, we need to release the handle we received a->release(); } return b; } // Example registration of the behaviour r = engine->RegisterGlobalBehaviour(asBEHAVE_REF_CAST, "derived@ f(base@)", asFUNCTION(refCast<base,derived>), asCALL_CDECL); assert( r >= 0 ); r = engine->RegisterGlobalBehaviour(asBEHAVE_IMPLICIT_REF_CAST, "base@ f(derived@)", asFUNCTION(refCast<derived,base>), asCALL_CDECL); assert( r >= 0 );
For this reason the application needs to register all the inherited methods and properties for the derived classes, which may lead to a bit of duplicate code. However, you may be able to avoid the duplication through a bit of clever thinking. Here is an example of registering the methods and properties for a base class and the derived class (registration of behaviours has been omitted for briefness):
// The base class class base { public: virtual void aMethod(); int aProperty; }; // The derived class class derived : public base { public: virtual void aNewMethod(); int aNewProperty; }; // The code to register the classes // This is implemented as a template function, to support multiple inheritance template <class T> void RegisterBaseMembers(asIScriptEngine *engine, const char *type) { int r; r = engine->RegisterObjectMethod(type, "void aMethod()", asMETHOD(T, aMethod), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectProperty(type, "int aProperty", offsetof(T, aProperty)); assert( r >= 0 ); } template <class T> void RegisterDerivedMembers(asIScriptEngine *engine, const char *type) { int r; // Register the inherited members by calling // the registration of the base members RegisterBaseMembers<T>(engine, type); // Now register the new members r = engine->RegisterObjectMethod(typem "void aNewMethod()", asMETHOD(T, aNewMethod), asCALL_THISCALL); assert( r >= 0 ); r = engine->RegisterObjectProperty(type, "int aProperty", offsetof(T, aProperty)); assert( r >= 0 ); } void RegisterTypes(asIScriptEngine *engine) { int r; // Register the base type r = engine->RegisterObjectType("base", 0, asOBJ_REF); assert( r >= 0 ); RegisterFathersMethods<base>(engine, "base"); // Register the derived type r = engine->RegisterObjectType("derived", 0, asOBJ_REF); assert( r >= 0 ); RegisterSonsMethods<derived>(engine, "derived"); }