Results 1 to 8 of 8

Thread: Pointers :P

  1. #1

    Pointers :P

    Couple of quick questions about pointers as they always drive me nuts in Delphi, especially when doing more complex stuff.

    1) I have this simple routine for extracting previously decompressed images that I store in TBitmaps. The function returns type TBitmap.
    FaPBitmap is an array of ^TBitmap

    function ExtractImage(Index: Integer): TBitmap;
    begin
    Result := FaPBitmap[Index]^;
    end;

    The problem I have is when I use a TBitmap variable in the calling routines of this function to hold the result, when I destroy the temporary bitmap after I have finished copying it to a DX surface, the orginial is destroyed. This is because I passed back a pointer to the original! How can I get around this? I want to pass the actuall thing itself as a 'new' entity for the calling procedure to destroy once done. At the moment I can display each image once lol...

    2) How can you increment a pointer by x number of bytes? Inc(myPointer) works, but how can I add say 256 for instance?
    http://www.c5software.co.uk (site is being developed at the moment)

  2. #2

    Pointers :P

    1) Create new bitmap and use AssignTo to copy content of original bitmal?
    2) Incrementing a pointer by x number of bytes: [pascal][background=#FFFFFF][normal=#000000][number=#0000FF][string=#0000FF][comment=#248F24][reserved=#000000]// If pointer is PByte then:
    Inc(p, 256);
    // else
    p:= Pointer(Cardinal(p) + 256);[/pascal]
    There are only 10 types of people in this world; those who understand binary and those who don't.

  3. #3

    Pointers :P

    When doing this I would write.....

    function ExtractImage(Index: Integer): TBitmap;
    begin
    Result:=TBitmap.Create; // create a bitmap for the return
    Result.assign(FaPBitmap[Index]^);
    end;


    Hope this helps a little.
    Stevie
    <br />
    <br />Don't follow me..... I'm lost.

  4. #4

    Pointers :P

    Quote Originally Posted by Stevie56
    When doing this I would write.....

    function ExtractImage(Index: Integer): TBitmap;
    begin
    Result:=TBitmap.Create; // create a bitmap for the return
    Result.assign(FaPBitmap[Index]^);
    end;


    Hope this helps a little.
    Hi, that's exactly what I ended up doing

    Thanks! And thanks Clootie
    http://www.c5software.co.uk (site is being developed at the moment)

  5. #5

    Pointers :P

    Are you absolutely, positively sure that you need a ^TBitmap (a pointer to a pointer, in other words). IME it's pretty rare to require pointers to classes, especially since Delphi has var parameters in functions.

    Just making sure, that's all...
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

  6. #6

    Pointers :P

    Quote Originally Posted by Alimonster
    Are you absolutely, positively sure that you need a ^TBitmap (a pointer to a pointer, in other words). IME it's pretty rare to require pointers to classes, especially since Delphi has var parameters in functions.

    Just making sure, that's all...
    Not entirely sure what you mean... I ended up just passing back the pointer to the TBitmap, this allows me to blit the bitmap to a DX surface, without creating a new TBitmap object first. Seems very fast, is there a faster more recommended way of drawing in tile based games? It seems effective to extract my bitmaps, store in a large array and pass pointers to the paint routine as and when required?

    Sorry for the long wait in my reply btw... I am trying to code the entire game myself (MMORPG), which is taking a lot of time and energy.
    http://www.c5software.co.uk (site is being developed at the moment)

  7. #7

    Pointers :P

    What he means is that an object in Delphi allready is a pointer. Another method you might consider (and might even be faster) is using a TList and simply adding the TBitmap objects to it. A TList is way faster than an array and the principle is the same!
    Do it by the book, but be the author!
    <br />
    <br />Visit the Lion Productions website at:
    <br />http://lionprod.f2o.org

  8. #8

    Pointers :P

    TheLion got my meaning there. I'll expand on my previous post.

    All classes are implicit pointers. This means that you can change an object without requiring var parameters. E.g.

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000][number=#C00000][reserved=#000000][string=#00C000]type
    TWhatever = class
    private
    FValue: Integer;
    public
    property Value: Integer read FValue write FValue;
    end;

    procedure ChangeMe(xyz: TWhatever);
    begin
    xyz.Value := 321;
    end;

    procedure Test;
    var
    Blah: TWhatever;
    begin
    Blah := TWhatever.Create;
    Blah.Value := 123;
    ShowMessage('The value of blah is ' + IntToStr(Blah.Value));

    ChangeMe(Blah);
    ShowMessage('The value is now ' + IntToStr(Blah.Value));
    Blah.Free;
    end;[/pascal]
    Notice how the above changes the value of blah. If you expected it to be copied-by-value then your intuition ain't right. Notice, though, that this behaviour is the same as the pointer.

    Next, consider the size of a class:

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000][number=#C00000][reserved=#000000][string=#00C000]procedure Example2;
    begin
    if SizeOf(TWhatever) = SizeOf(Pointer) then
    ShowMessage('Now that''s interesting...')
    else
    ShowMessage('This never gets shown');
    end;[/pascal]

    A class instance will be four bytes in size - it's a pointer.

    Classes are pointers, which means that it's very uncommon to require pointer-to-classes (like your ^TBitmap). You can allocate memory for your classes, initialise it to zero, and call relevant constructors when you create the class. Once that's done, your class will have memory associated with it (which is why you need to free it).

    Passing classes in the standard fashion ("procedure Whatever(Someclass: TSomething)") lets you change the class's fields, but not the area of memory to which it's assigned. The only time you'd want to pass a pointer to the class would be if you wanted to point the object to somewhere else.

    Remember how I said before that classes point to a chunk of memory? Maybe we would want to point it somewhere else. How about the following, where we have two allocated buttons (maybe sitting on a form) and one that's a reference (no memory allocated, just pointing to one of the buttons for some reason):

    [pascal][background=#FFFFFF][comment=#0000FF][normal=#000000][number=#C00000][reserved=#000000][string=#00C000]procedure TForm1.ChangeMe(var AButton: TButton);
    begin
    AButton := Button2;
    end;

    procedure TForm1.Blah;
    var
    Temp: TButton;
    begin
    Temp := Button1; // point to the first button

    // do something else

    ChangeMe(Temp);

    // temp will point to the second button now
    end;[/pascal]

    Notice the change in behaviour here -- we want to change the area of memory to which our class instance points. Therefore, we have to pass in a var parameter for ChangeMe -- if we don't then copy by value will take place and our button won't point to somewhere else and the reference will still point to the first button instead of the second. You can also use a pointer-to-TButton here in the ChangeMe procedure but I'd recommend against it.

    So, in short, you only want to use a pointer-to-class if you want to change the area of memory that an object points to. It's not more efficient to use pointers-to-classes since classes are already pointers -- in fact, it may be slightly less efficient since you have to dereference them twice.

    Now, thinking about the above, it should be clear why I said something like "they're pretty rare, especially because of var params" (paraphrasing myself). In short, if you need to change a object's fields, you can just pass it in as normal. If you want to point the object to somewhere else (being careful to .free it if you .created it, of course), then you can pass the object as var parameter (but without using a pointer to it).

    Of course, you may have a reason to use ^TBitmaps instead of TBitmaps + var parameters where necessary. My intuition says that this isn't too likely, though.
    "All paid jobs absorb and degrade the mind."
    <br />-- Aristotle

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •