Recent

Author Topic: Class 'Private' NOT working???  (Read 6952 times)

darksky

  • New Member
  • *
  • Posts: 15
Class 'Private' NOT working???
« on: December 18, 2014, 06:05:59 am »
Please look at the code below:

Code: [Select]
{$MODE OBJFPC}
PROGRAM prog;

TYPE
TestClass = Class
private
a : integer;
public
b : integer;
constructor init;
end;

TestClass2 = Class
c : integer;
constructor init;
end;

constructor TestClass.init;
begin
a := 13;
b := 49;
end;

constructor TestClass2.init;
begin
a := 07; (* This private member isn't supposed to be inherited. Is it? *)
b := 70;

c := 58;
end;

VAR
cl : TestClass;
cl2: TestClass2;

BEGIN
cl := TestClass.init;
cl2 := TestClass2.init;

Writeln(cl.a, ' ', cl.b);
(* How are we able to compile with trying to access a Private member in MAIN??*)

Writeln(cl2.a, ' ', cl2.b, ' ', cl2.c);
(* How are we able to even access Inherited Member of Parent in Descendent Class? *)
cl2.a := 85;
(* This also compiles and works fine?? *)

ReadLn;
END.

1. Am I missing something or what? The private member is supposed to be private to methods in the Class, isn't it? How are we able to access it in the MAIN and the descending/Children classes??

2. Why use SetLength on AnsiString when we can do this:

Code: [Select]
VAR
an : AnsiString;

BEGIN
an := 'Hello World';
Writeln(an);
SetLength(an, 5);
Writeln(an); (* Prints "Hello" *)

(*But then after resizing the Length, this is do-able!*)
an := 'Hello World!'
END.

I mean why does the ref.pdf mention the use of SetLength on AnsiString when we can do resize the String even after setting it's Length??

3. Why can't we access 0th element of AnsiString?
4. Why can't we implement C language Strlen on AnsiString (I know it's do-able with PCHAR) but why not AnsiString?? (I tried but it fin the null character before the end of the string..)

5. Does GetMem rely on other libraries? Can we use it in DLL and rest assured that it won't fail ??

Thanks..

darksky

  • New Member
  • *
  • Posts: 15
Re: Class 'Private' NOT working???
« Reply #1 on: December 18, 2014, 06:12:23 am »
Also, this page (http://www.freepascal.org/docs-html/prog/progsu24.html) says we need to have:

{$GOTO ON}

to use Labels but the labels worked fine without me writing above!

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Class 'Private' NOT working???
« Reply #2 on: December 18, 2014, 06:29:38 am »
1. You need to move TestClass2 to separate unit or use strict modifier in ancestor class :
Code: [Select]
TestClass = Class
strict private
a : integer;
public
b : integer;
constructor init;
end;

2,3, 4. AnsiString :
Quote
Ansistrings are strings that have no length limit. They are reference counted and are guaranteed to be null terminated. Internally, an ansistring is treated as a pointer: the actual content of the string is stored on the heap, as much memory as needed to store the string content is allocated.
. More info : http://www.freepascal.org/docs-html/ref/refsu12.html

Index 0 points to AnstiString control structure where lies its size and code page information. So modifying this location have severe consequences for string handling, resulting crashes and memory leaks.

5. GetMem : It depends on target platform and use of different memory manager. In Linux you can use cmem unit which provides memory manager compatible for C language. This helps linking your units against programs written with C/C++ language.

6. If you use Lazarus IDE then GOTO (and others, like ansistring etc) is by default enabled when compiling with it.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Class 'Private' NOT working???
« Reply #3 on: December 18, 2014, 07:01:51 am »
1. Am I missing something or what? The private member is supposed to be private to methods in the Class, isn't it? How are we able to access it in the MAIN and the descending/Children classes??
All classes in the same unit has a friendship relation, thus the private access modifier is private only to classes outside the unit. Use strict private if you want the real private access modifier.
2. Why use SetLength on AnsiString when we can do this:
...
I mean why does the ref.pdf mention the use of SetLength on AnsiString when we can do resize the String even after setting it's Length??
Because it's possible, and it's not always desirable to do as in your example. AnsiString is quite often used as a buffer, e.g.: saving output of a process. Reading input stream cannot be done simply by appending to AnsiString, because the process' output stream expects a buffer to write to and the buffer size itself. Therefore, we need to use SetLength first to allocate storage, before passing the AnsiString by reference.
3. Why can't we access 0th element of AnsiString?
It's semantically undefined, and implementation details may change, therefore it's normally prohibited (though certain hacks will make it possible).
4. Why can't we implement C language Strlen on AnsiString (I know it's do-able with PCHAR) but why not AnsiString?? (I tried but it fin the null character before the end of the string..)
Two reasons:
  • Not needed, AnsiString knows its own length and can be retrieved in O(1)
  • The function is not overloaded for AnsiString (though you can simply typecast AnsiString to PChar)
5. Does GetMem rely on other libraries? Can we use it in DLL and rest assured that it won't fail ??
No, but can be. FPC memory manager is user replacable. The default memory manager is statically linked, so each dll / exe has its own copy. Mixing these will confuse the manager and results in undefined behavior. If you can ensure you always call the dll ones, then it will be OK (though this means the one in the exe is useless).
Also, this page (http://www.freepascal.org/docs-html/prog/progsu24.html) says we need to have:

{$GOTO ON}

to use Labels but the labels worked fine without me writing above!
The switch is off by default but your fpc.cfg might enable it.

darksky

  • New Member
  • *
  • Posts: 15
Re: Class 'Private' NOT working???
« Reply #4 on: December 18, 2014, 12:23:52 pm »
Thank you, @Leledumbo and @Cyrax I really appreciate it..

I hate to say it but I have some questions..

I'm sorry to bug you, but when you said:
Quote
No, but can be. FPC memory manager is user replacable. The default memory manager is statically linked, so each dll / exe has its own copy. Mixing these will confuse the manager and results in undefined behavior. If you can ensure you always call the dll ones, then it will be OK (though this means the one in the exe is useless).

1. I think you misunderstood my question (looking at the "exe" part), I meant that while making a DLL from Freepascal, can I use the GetMem function inside the Pascal DllMain?

I know I could just try it myself to see if it works, but I thought of a possibility where it would work in mine and not in others! Can that happen? Or should I use the Windows HeapAlloc() instead?

2. Why does Pascal have #? I mean I have read it being referred to as a Control String with unsigned int between 0 and 255, and have seen it being used #0 as Null character, but I don't think I understand it fully, how do you think of it as someone programming in Pascal?

3. Why does Pascal have "file of Integer", "file of char", "file of record" when we could just have a single thing that could do it all just like in other languages?

Say I'm making a School/Hospital Fee Application, then I would use File of Record (as the data will most likely be a structure)? Is it for such purpose?

Anyway, why bother with having so many file of _specific_data_type at all?


And btw, is the ref.pdf in FP installation (\doc) outdated or something? It says the Class Constructor name must be Create, but I am using one called Init and it's working just fine.

And I use the Freepascal IDE (that console IDE that comes by default with FreePascal)

Thanks.,..
« Last Edit: December 18, 2014, 12:39:58 pm by darksky »

minesadorada

  • Sr. Member
  • ****
  • Posts: 452
  • Retired
Re: Class 'Private' NOT working???
« Reply #5 on: December 18, 2014, 12:27:19 pm »

All classes in the same unit has a friendship relation, thus the private access modifier is private only to classes outside the unit. Use strict private if you want the real private access modifier.
Well I learned something new today.  This might explain a bug I was having trouble squashing in another project.
GPL Apps: Health MonitorRetro Ski Run
OnlinePackageManager Components: LazAutoUpdate, LongTimer, PoweredBy, ScrollText, PlaySound, CryptINI

Basile B.

  • Guest
Re: Class 'Private' NOT working???
« Reply #6 on: December 18, 2014, 04:19:51 pm »
2. Why does Pascal have #? I mean I have read it being referred to as a Control String with unsigned int between 0 and 255, and have seen it being used #0 as Null character, but I don't think I understand it fully, how do you think of it as someone programming in Pascal?

It's used to insert an ansi char based on its integer value. For example in string litterals, if you want to include a single quote: 'mystring'#38'includes a single quote'.


3. Why does Pascal have "file of Integer", "file of char", "file of record" when we could just have a single thing that could do it all just like in other languages?

This is a legacy, old-fashioned, thing. To be honnest I think nobody uses this anymore. You can use a TMemoryStream or a TFileStream to handle files.

The fact is that someone over this planet seems to teach Pascal with these old things because there is periodically some guys who comes with a question about the file of usage.Learn write()/read() etc for the console usage, don't bother with this when it's used for files. Since, i dunno, maybe 20 years, people uses streams, based on the OS API.


And btw, is the ref.pdf in FP installation (\doc) outdated or something? It says the Class Constructor name must be Create, but I am using one called Init and it's working just fine.

What's matter is the constructor keyword, its name is just a regular identifier. It's a shared convention to name it Create.
« Last Edit: December 19, 2014, 03:02:51 pm by Basile B. »

Cyrax

  • Hero Member
  • *****
  • Posts: 836
Re: Class 'Private' NOT working???
« Reply #7 on: December 18, 2014, 06:10:35 pm »
Thank you, @Leledumbo and @Cyrax I really appreciate it..

I hate to say it but I have some questions..

I'm sorry to bug you, but when you said:
Quote
No, but can be. FPC memory manager is user replacable. The default memory manager is statically linked, so each dll / exe has its own copy. Mixing these will confuse the manager and results in undefined behavior. If you can ensure you always call the dll ones, then it will be OK (though this means the one in the exe is useless).

1. I think you misunderstood my question (looking at the "exe" part), I meant that while making a DLL from Freepascal, can I use the GetMem function inside the Pascal DllMain?

Yes you can but then you will be using DLL's memory manager, not main applications ones. It can be shared by creating another DLL  which can be used to replace both executable's and DLL's memory manager.

Quote
I know I could just try it myself to see if it works, but I thought of a possibility where it would work in mine and not in others! Can that happen? Or should I use the Windows HeapAlloc() instead?

No need. When you use GetMem, FPC will use HeapAlloc() internally when target system is Windows OS.

Quote
2. Why does Pascal have #? I mean I have read it being referred to as a Control String with unsigned int between 0 and 255, and have seen it being used #0 as Null character, but I don't think I understand it fully, how do you think of it as someone programming in Pascal?

I think that is relic and convenience functionality. Also nowadays you aren't limited for 0-255 range, you can use 0-65535 or larger if you want Unicode/Wide character codes.

Quote
3. Why does Pascal have "file of Integer", "file of char", "file of record" when we could just have a single thing that could do it all just like in other languages?

Say I'm making a School/Hospital Fee Application, then I would use File of Record (as the data will most likely be a structure)? Is it for such purpose?

Anyway, why bother with having so many file of _specific_data_type at all?

Relic from ancient days. For School/Hospital Fee Application you should use ORM and databases. See tiOPF for example.

Quote
And btw, is the ref.pdf in FP installation (\doc) outdated or something? It says the Class Constructor name must be Create, but I am using one called Init and it's working just fine.

And I use the Freepascal IDE (that console IDE that comes by default with FreePascal)

Thanks.,..

If you are using textmode IDE, then you might want to check out fpc.cfg and fp.cfg configuration files.

Leledumbo

  • Hero Member
  • *****
  • Posts: 8757
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Class 'Private' NOT working???
« Reply #8 on: December 18, 2014, 06:43:14 pm »
1. I think you misunderstood my question (looking at the "exe" part), I meant that while making a DLL from Freepascal, can I use the GetMem function inside the Pascal DllMain?
I guess so. The answer is yes, then.
2. Why does Pascal have #? I mean I have read it being referred to as a Control String with unsigned int between 0 and 255, and have seen it being used #0 as Null character, but I don't think I understand it fully, how do you think of it as someone programming in Pascal?
Not all characters are typable but they're needed, thus something else is required to define them. Nowadays it's also used to define Unicode characters on keyboard without native support for such characters.
3. Why does Pascal have "file of Integer", "file of char", "file of record" when we could just have a single thing that could do it all just like in other languages?

Say I'm making a School/Hospital Fee Application, then I would use File of Record (as the data will most likely be a structure)? Is it for such purpose?

Anyway, why bother with having so many file of _specific_data_type at all?
The original concept of Pascal files are structured record. Thus, instead of manually decoding each bytes into something meaningful, one can simply use read/write statement to manipulate file contents. This is of course has limitations such as dynamicity of the file contents but in a lot of cases can shorten programs significantly than unstructured ones. Not to mention its benefit to easily teach and learn than random access files.
And btw, is the ref.pdf in FP installation (\doc) outdated or something? It says the Class Constructor name must be Create, but I am using one called Init and it's working just fine.
Perhaps that part needs adjustment. Create is just a convention (from Delphi era), Init is the older one (from Turbo Pascal with Objects era). TObject, however, defines the very base constructor named Create. All classes will inherit this. Whether you define your own differently named constructor or not, Create will always be callable. No problem comes if you don't use class references, but once you do, there might be. consider the following code:
Code: [Select]
type
  TObjectClass = class of TObject;
...
function SomeFactoryMethod(AClass: TObjectClass): TObject;
begin
  Result := AClass.Create;
end;
Since TObject always defines constructor named Create, above code is valid. Thus, any class extending TObject (which is any class) can be passed as parameter of SomeFactoryMethod. Now, when you define a constructor for your class, named differently from Create and has specific code to execute, you can no longer use SomeFactoryMethod to create your class' instance. The reason is that instead of your constructor, it will always call the default Create inherited from TObject, so your specific code will not be executed.

darksky

  • New Member
  • *
  • Posts: 15
Re: Class 'Private' NOT working???
« Reply #9 on: December 19, 2014, 12:54:54 pm »
Thank you so much.. I really appreciate it.. :)

 

TinyPortal © 2005-2018