With classes the script writer can declare new data types that hold groups of properties and methods to manipulate them.
Script classes are reference types, which means that multiple references or handles can be held for the same object instance. The classes uses automatic memory management so the object instances are only destroyed when the last reference to the instance is cleared.
The class methods are implemented the same way as global functions, with the addition that the class method can access the class instance properties through either directly or through the 'this' keyword in the case a local variable has the same name.
// The class declaration class MyClass { // A class method void DoSomething() { // The class properties can be accessed directly a *= 2;
// The declaration of a local variable may hide class properties int b = 42;
// In this case the class property have to be accessed explicitly this.b = b; }
// Class properties int a; int b; }
A class can implement specific methods to overload operators. This can simplify how the object instances are used in expressions, so that it is not necessary to explicitly name each function, e.g. the opAdd method translates to the + operator.
Another useful feature is the ability to implement property accessors, which can be used either to provide virtual properties, i.e. that look like properties but really aren't, or to implement specific routines that must be executed everytime a property is accessed.
A script class can also inherit from other classes, and implement interfaces.
Class constructors are specific methods that will be used to create new instances of the class. It is not required for a class to declare constructors, but doing so may make it easier to use the class as it will not be necessary to first instanciate the class and then manually set the properties.
The constructors are declared without a return type, and must have the same name as the class itself. Multiple constructors with different parameter lists can be implemented for different forms of initializations.
class MyClass { // Implement a default constructor MyClass() { }
// Implement the copy constructor MyClass(const MyClass &in other) { // Copy the value of the other instance }
// Implement other constructors with different parameter lists MyClass(int a, string b) {} MyClass(float x, float y, float z) {} }
The copy constructor is a specific constructor that the compiler can use to build more performatic code when copies of an object must be made. Without the copy constructor the compiler will be forced to first instanciate the copy using the default constructor, and then copy the attributes with the opAssign method.
One constructor cannot call another constructor. If you wish to share implementations in the constructors you should use a specific method for that.
If a class isn't explicitly declared with any constructor, the compiler will automatically provide a default constructor for the class. This automatically generated constructor will simply call the default constructor for all object members, and set all handles to null. If a member cannot be initialized with a default constructor, then a compiler error will be emitted.
How the members shall be initialized can also be defined directly in the declaration of the members. When this is done the initialization expression will automatically be compiled in the constructor without the need to write the initialization again.
It is normally not necessary to implement the class destructor as AngelScript will by default free up any resources the objects holds when it is destroyed. However, there may be situations where a more explicit cleanup routine must be done as part of the destruction of the object.
The destructor is declared similarly to the constructor, except that it must be prefixed with the ~ symbol (also known as the bitwise not operator).
class MyClass { // Implement the destructor if explicit cleanup is needed ~MyClass() { // Perform explicit cleanup here } }
Observe that AngelScript uses automatic memory management with garbage collection so it may not always be easy to predict when the destructor is executed. AngelScript will also call the destructor only once, even if the object is resurrected by adding a reference to it while executing the destructor.
It is not possible to directly invoke the destructor. If you need to be able to directly invoke the cleanup, then you should implement a public method for that.
Classes add a new type of function overload, i.e. const overload. When a class method is accessed through a read-only reference or handle, only methods that have been marked as constant can be invoked. When the reference or handle is writable, then both types can be invoked, with the preference being the non-const version in case both matches.
class CMyClass { int method() { a++; return a; } int method() const { return a; } int a; } void Function() { CMyClass o; const CMyClass @h = o;
o.method(); // invokes the non-const version that increments the member a h.method(); // invokes the const version that doesn't increment the member a }