AS3 language 101 for C/C++ coders

This article covers aspects of ActionScript 3 that would be helpful to C/C++ application engineers transitioning to application development in Flex and Flash.

I’ve used C/C++ through most of my educational and professional career. I’ve also done a respectable share of Javascript and Perl. ActionScript 3 could be viewed as an interesting blend of features from all of these languages. Actionscript 3 conforms to the ECMAscript 4 spec. So, it is a standard languange. In addition to the standard language syntax, AS3 contains a custom class framework for working with Flex/Flash.

The following are areas in the AS3 language that I personally found interesting.

Type declarations

Compared to C/C++, the first syntax oddity that you’ll notice is how AS3 declares it’s variable types. All type declarations are in post-fix notation. For example, in C you would define a function like:

int myFunction(char *str);

In AS3 this same function declaration looks like:

function myFunction(str:String) : int

 

Typecasting

In AS3, think of typecasting like calling the constructor of the type. Functionally, this isn’t what happens, but the syntax is what it appears to be doing.

In C: int i = (int)somefloat;
In AS3:    var i:int = int(somefloat);

If you see what appears to be something calling the constructor of a class or type but it does not use “new”, it’s not calling a constructor. It’s performing a typecast. For example:

var foo:SomeClass = SomeClass(someObject);
var bar:SomeClass = new SomeClass(someObject);

The first line is typecasting “someObject” into SomeClass. The second line is creating a new SomeClass object, passing “someObject” as a parameter to the constructor. This subtle difference can have wide ranging effects (new object vs. reusing an existing object, etc.).  Depending on what the class constructor takes as a parameter, it is possible that both the typecast and the constructor would compile with no errors/warnings in all situations.  So, be careful.  The difference between a typecast and a new object is just the "new" keyword.

 

Variable scope

Variables are scoped to the function. ActionScript employs a system called "variable hoisting", which implicitly pulls all variable declarations in the function (even ones in nested blocks) to the top of the function at compile time.  For example:

public function doSomething() : void{var foo:int = 4;if (foo){var bar:int = 2;}}

With viable hoisting, all declared variables in a function are moved to the top of the function block at compile time. In the above example, the compile time result looks like:

public function doSomething() : void{var foo:int;var bar:int;foo = 4;if (foo){bar = 2;}}

Note that the "bar" variable is now in scope for the entire function.  This subtle variable handling in AS3 may lead to unintended situations since any use of the "bar" variable before the "if(foo)" block is now valid, even though it is not declared until inside the if() block.  AS3 will complain if you declare the same variable more than once in the same function, but it won’t complain if you use a variable before it’s declared.

void *

In AS3, you can use the wild card type to mimic the "void *" type.  For example, say you have a factory object that can return objects of many types.  This can be implemented as such:

public function wildcard() : void{var anything:* = ObjectFactory.getData();}

Run time type checking

Since you can pass things around as anything using the wildcard type (void *), you need a way to check the type of the object at runtime. To do this, you can use the “is” directive:

public function doSomething() : void{var something:* = getData();if (something is String){// handle string logic}else{// do something else}}

This allows for runtime type checking which allows your application to perform different logic depending on what the given object is.

No function overloading

There is no function overloading in AS3. However, you can implement a system that mimics function overloading. For example, in C++ you might have some function definitions like:

int doSomething(int i);int doSomething(char *str);

In AS3, you can’t overload a function, but the language allows you to make use of the type wildcard “*” and use the "is" directive as a way of performing runtime checks and branching based on what was passed in. For example:

function doSomething(obj:*) : int{if (obj is int)// do int stuffelse if (obj is String)// do string stuffelse// what type did you give me?
}

No operator overloading

AS3 has no way to override the meaning of “+”, “=”, or any other operator. The closest functionality is the get/set member accessors that you can declare to handle the getting and assignment of class members.

Everything is an object

All types within AS3 are derived classes of the base class “Object”. Even if a class does not “extend Object”, it still does. This means when you pass anything to a function, you are passing that data by reference (pointer) in all cases. If the called function modifies the object you passed, your version of the data will be modified as well.

However, there are some exceptions. Basic types like int, Number, and String are objects as well, but their implementation performs reference counting to make them behave like stack objects. If the called function simply assigns new values to variables of these basic types, the data in the caller function does not get modified.

Only one packaged class per file

When implementing AS3 classes, you can only have one class definition per package declaration per AS file. For example:

MyClass.as

package my.class.package{public class MyClass{public function MyClass(){...}}}

Fig. 1

MyClass.as

package my.class.package{public class MyClass{public function MyClass(){...}}}class MyPrivateClass{public function MyPrivateClass(){...}}

Fig. 2

MyClass.as

package my.class.package{public class MyClass{public function MyClass(){...}}public class AnotherClass{public function AnotherClass{...}}}

Fig. 3

Fig. 1 and 2 are valid in AS3. Fig. 3 is not valid. AS3 does not allow you to have more than one class inside a package declaration and you can only have one package declaration per file. The interesting thing to note is that the “PrivateClass” in Fig. 2 is only accessable to code inside that file. Outside that file, the “PrivateClass” is an unknown type. You can use the construct in Fig. 2 to hide implementation classes from the rest of the world.

Being limited to one public class per file may not be a huge problem, but it may come as a logistical hurdle if you are expecting to define multiple classes within the same file. Plan your file structure accordingly.

virtual functions

The major difference between AS3 and C++ when it comes to inherited functions is the fact that the functions in a derived class do not override the base class functions unless you declare a method as “override“. Without this declaration, the base class version of the function will be called in all cases.

You can think of this as almost the opposite of C++’s “virtual” declaration. In C++, once a function is declared virtual, that function is automatically virtual for all derived classes regardless if the derived class declares it as virtual. In AS3, the derived class controls what functions are “virtual” (overridden).

dynamic_cast

In AS3, you will find yourself dealing with interfaces. These are similar in concept to abstract base classes in C++. Objects that implement an interface will be passed around as instances of that interface. So, given an object of a specific interface, how do you get the object as an instance of its subclass? You use the “as” functionality. For example:

var someInterface:ISomeInterface = factory.getSomeInterface();var someClass:SomeClass = (someInterface as SomeClass);

If "someInterface" is actually an instance of "SomeClass" or a derived class of "SomeClass", the variable "someClass" will be a reference to that object.  If "someInterface" is an instance of some other class, the "someClass" variable will be null.

Raw character strings

AS3 has a primative string type named “String”. You can access the characters of the string and do things with them, but what if you want access to the raw ASCII or UTF8 bytes? The easiest way to do this is via the ByteArray() class. You can write a string into a ByteArray object and then pull it back out as raw bytes.

 

Well, I hope this is useful to anyone making the transition to Flex/ActionScript from C/C++. If you have any questions, found an error in my assessment, or just want to say something, please leave a comment. We’re trying to make Flex development as easy as possible for everyone and any feedback is much appreciated.

Thanks!