PDA

View Full Version : Friend members in Delphi



pstudio
15-06-2011, 01:09 PM
Language: Delphi XE

Problem:
There are two classes. A and B. A will have a list of derivatives from B. In B there is a reference to the instance of A which currently owns the instance of B. This reference is a read only member and can't be changed by the user. The idea is that when an instance of B is added to A's list, the reference in B will be updated to point to A. A and B are written in seperate unit files.

My question is how can I change them member in B from A? I know I can put A and B in the same unit file and take advantage of Delphi's scope rules, but I would like to keep the two classes in seperate unit files.
In c++ you can declare a class as a friend and expose certain members to that class. Is there something equivalent in Delphi? Are there any other suggestions on how to solve this problem?

Ñuño Martínez
15-06-2011, 01:28 PM
Do you mean something like this:


A = CLASS
PRIVATE
fListOfB: ARRAY OF B;
PUBLIC
PROCEDURE AddB (aB: B);
FUNCTION GetB (Ndx: INTEGER): B;
END;

/ ---- /

B = CLASS
PRIVATE
A_Owner: A;
END;
VCL has public "Owner". I'm not sure if it's writeable, but "Parent" is. BTW you can control the assignment.



PROCEDURE A.AddB (aBitem: B)
BEGIN
B.Owner := SELF;
fListOfB[fLast] := B;
END;

/ ----- /

B = CLASS
PRIVATE
fOwner: A;

PROCEDURE SetOwnerProperty (aOwner: A);
PUBLIC
PROPERTY Owner: A READ fOwner WRITE SetOwnerProperty;
END;

PROCEDURE B.SetOwnerProperty (aOwner: A);
BEGIN
IF SELF.fOwner != NIL THEN
SELF.fOwner.RemoveItem (SELF);
SELF.fOwner := aOwner;
END;

pstudio
15-06-2011, 02:30 PM
Do you mean something like this:


A = CLASS
PRIVATE
fListOfB: ARRAY OF B;
PUBLIC
PROCEDURE AddB (aB: B);
FUNCTION GetB (Ndx: INTEGER): B;
END;

/ ---- /

B = CLASS
PRIVATE
A_Owner: A;
END;


Yes. If both declarations are in the same unit file I can easily write:



procedure A.AddB(aBitem: B)
begin
aBitItem.A_Owner := Self;
end


However A and B are declared in two seperate unit files so that is not possible. Right now I've simply made A_Owner public writeable but I would like to make it only readable and still be able to change it from only A.

chronozphere
15-06-2011, 04:03 PM
I also encounter this problem often. Pascal forces you to put all "friend" classes into the same unit, which I dont really like. When it comes to fields/methods, you can either make it private/protected so only classes in the same unit (or derived ones respectively) can access it. The other option is to make it public, in which case ALL other code can access the element. There is nothing inbetween.

I think that friend-classes in C++ are not the right thing either (Allthought I haven't closely looked at them, so this statement hasn't got any value). I do like JAVA's package system. You can make things accessible to all classes that live inside the same package while they are in different files. All you need is one line at the top of each file telling in which package the file is. I wish pascal had this feature! :(

Ñuño Martínez
15-06-2011, 04:24 PM
I do like JAVA's package system. You can make things accessible to all classes that live inside the same package while they are in different files. All you need is one line at the top of each file telling in which package the file is. I wish pascal had this feature! :(

Yes, that feature would be great. I think we should request this feature to Delpi and FreePascal, instead to steal weird and ugly features from C++ (i.e. why to use "generics" having "interfaces"?). Or may be to expand the "LIBRARY" stuff not only to build dynamic libraries (dll, so, dylib, etc). Just thinking out loud.

pstudio
15-06-2011, 06:09 PM
@chronzphere
So what option do you end up taking? Do you place multiple classes into one huge unit or do you make the field public and then instruct not to write to the field?

@?ëu?±o
Something like that would be great, but I fear that it doesn't fit in well with how Pascal is compiled.