NAME

@dynamic_cast - Safely cast an object to a different type at runtime

SYNOPSIS

@dynamic_cast<CLASS-NAME[*]> {INPUT}
@dynamic_cast<$shell_variable> {INPUT}
@dynamic_cast<@object.reference> {INPUT}

DESCRIPTION

The @dynamic_cast directive is used to safely cast an object to a different type at runtime.

The output of the @dynamic_cast directive will be either:

TARGETS

The target of the @dynamic_cast directive is the type to which you want to cast the object. The target is given in the <...> bracket pair and can be one of the following:

If a class name is given directly, the compiler will emit a warning if the class is not defined in the current context.

If a shell variable or object reference is given, the compiler will expect to resolve the class name at runtime.

If an object reference is given, it can refer to either a data member or a method. I.e., all kinds of object references are acceptable here. If the reference refers to a method, that method will be implicitly executed in a supershell, and its output will be treated as the target class name.

EXAMPLE

The safest way to use @dynamic_cast is to specify the target class name directly:

@Object obj

@Object* castedObj=@dynamic_cast<Object> &@obj # Successful cast of obj to Object pointer

@castedObj=@dynamic_cast<Object> "Hello, world!" # Failed cast, returns @nullptr

shell_variable=@dynamic_cast<Object*> &@obj # Successful cast, pointer stored in $shell_variable

@UnrelatedObject unrelatedObj

echo @dynamic_cast<Object> &@unrelatedObj # Failed cast, echoes @nullptr

However, we can also give a shell variable or an object reference as the target class. In this case, no warnings will be emitted, and the class name will be resolved at runtime:

@class Object {
	@public member="Object"
}

shell_var="Object"

@Object obj

@Object* castedObj=@dynamic_cast<$shell_var> &@obj # Successful cast of obj to 'Object'

@Object* castedObj2=@dynamic_cast<@obj.member> &@obj # Successful cast of obj to 'Object'

@obj.member="NotARealClass"

@castedObj=@dynamic_cast<@obj.member> &@obj # Failed cast, no class called 'NotARealClass' exists, returns @nullptr

NOTES

The input may be any rvalue at all, including a pointer to an object, a call to a method, a simple string, a supershell/subshell, etc. Of course, in most cases, the input should be a pointer to an object.

The @dynamic_cast directive is most useful when the type of the object is not known at compile time, or when the object may be of a different type than expected.

You can safely verify that a cast was successful by checking if the result is @nullptr. If it is not, you can safely use the result as a pointer to the specified type.

@DerivedClass derived_object
@BaseClass* myPointer=@dynamic_cast<BaseClass> &@derived_object

if [[ @myPointer == @nullptr ]]; then
	echo "The cast is invalid"
else
	echo "All OK!"
fi

SEE ALSO