Node:SetType, Next:shl, Previous:SetLength, Up:Reference

### SetType

#### Synopsis

    procedure SetType (var SomeObject; VMT: PObjectType);

#### Description

The procedure `SetType` explicitly assigns a value to the implicit VMT field of an object. This is normally done implicitly when a constructor is called.

You can use this to write a polymorphic I/O routine which reads an object from a file. In this case, you cannot reasonably use `New` to allocate the storage, but you `GetMem` it and initialize the object manually using `SetType` before calling the constructor explicitly.

The only values you should assign to an object via `SetType` are actual VMT pointers that were obtained via `TypeOf`. In particular, declaring a record like the one shown in the description of `PObjectType` and assigning a pointer to it to an object via `SetType` will usually not work because the virtual method pointers are missing.

Since `SetType` is a dangerous feature, it yields a warning unless `{$X+}` is given.

#### Conforming to

`SetType` is a GNU Pascal extension.

#### Example

    program SetTypeDemo;

    type
      BasePtr = ^BaseObj;

      BaseObj = object
        constructor Load;
      end;

      ChildObj = object (BaseObj)
        constructor Load;
      end;

    constructor BaseObj.Load;
    begin
    end;

    constructor ChildObj.Load;
    begin
    end;

    {$X+}

    { This is somewhat fragmentary code. }
    function GetObject (var InputFile: File) = Result: BasePtr;
    const
      VMTTable: array [1 .. 2] of PObjectType =
        (TypeOf (BaseObj), TypeOf (ChildObj));
    var
      Size: Cardinal;
      TypeID: Integer;
      VMT: PObjectType;
    begin
      { Read the size of the object from some file and store it in `Size'. }
      BlockRead (InputFile, Size, SizeOf (Size));

      { Allocate memory for the object. }
      GetMem (Result, Size);

      { Read some ID from some file. }
      BlockRead (InputFile, TypeID, SizeOf (TypeID));

      { Look up the `VMT' from some table. }
      { Range checking wouldn't be a bad idea here ... }
      VMT := VMTTable[TypeID];

      SetType (Result^, VMT);

      { Now the object is ready, and the constructor can be called. }
      { Look up the correct constructor from some table and call it. }
    end;

    begin
    end.

#### See also

PObjectType, TypeOf, OOP.