IObject

There is a special interface called IObject defined as follows


$interface IObject
{
    AnyInterface QueryInterface(const ReflectedInterface& ri);
    const ReflectedClass& GetReflectedClass() const;
    void VisitObjects(IObjectVisitor& v) const;
    void OnGarbageCollect();
    void Destroy();
    ObjSysState& GetSysState();
};

Xcpp allows for the keyword 'isa' to be used to specify one or more interfaces that are implemented by a given class/struct. Each of the interfaces must inherit directly or indirectly from IObject.

Xcpp will generate code to implement this interface implicitly. For example


$struct X isa IObject {};

will compile successfully even though the methods of IObject haven’t been explicitly implemented (nor should they).

Note that global variables, frame variables or member variables of classes are allowed to implement IObject. i.e. it shouldn’t be assumed that only heap allocated objects are allowed to implement IObject, even though some of the functionality is specific to support for the CSpace garbage collector.


QueryInterface

The method QueryInterface() is similar in purpose to the function of the same name in the Microsoft COM interface IUnknown. It allows a client to cast interface pointers.

Consider the following interface definitions


$interface Ix : IObject {};
$interface Iy : IObject {};
$interface Iz : Ix,Iy {};
$interface Iw : IObject {};

Now suppose struct X implements Iz as follows


$struct X isa Iz {};

then the following code shows how we may cast between the different interface pointers using qicast<>.


X x;
ptr<Ix> px = &x;

// qicast<> can be used to cast to any other
// supported interface
ptr<Iy> py = qicast<Iy>(px);

// Casting to an interface that is not
// implemented by the object returns null.
assert(qicast<Iw>(px) == null);

For a given object we could define a binary relation between interfaces according to whether qicast will successfully take us from one interface to another interface. It is guaranteed that this relation cannot change while a process is running, and the relation will be reflexive, symmetric and transitive.