I have searched many sites and also there are questions on stackoverflow regarding my question but none answers them perfectly,so i decided to frame it as a new question.
According to me we use 'virtual' keyword when we need to define the function with same name and argument-list in both base and derived class.But in case of the destructos why we need virtual as the names would be different and there should be no confusion for the compiler as in case o constructor.
I am really confused with this.
In an object hierarchy, you can store your objects in a collection of your base object. In order to make sure your derived types' destructor is also executed during cleanup, you should make your dtors virtual.
However, you might not always want that, and hence c++ (I suppose yours is a c++ question), or the language gives you the chance to control this behaviour.
Related
Declaring members as published has advantages over public:
Ability to read/write the member in the Object Insepoctor of the IDE
RTTI and its uses
So is there ever a benefit to declaring members public instead of published? Does published have any downsides? Or should I always declare members published, as a rule?
PS: Not a duplicate; I read that question and all its answers prior to posting my question. The "possible duplicate" question explains the difference between the two keywords, but doesn't gives guidance when either should be used, or the advantages/disadvantages of using either.
Declaring as published imposes a storage cost because the size of your executable is swollen to contain the RTTI. Declaring as public avoids that cost. It's unlikely that would ever matter, especially given the immense size of modern Delphi executables, containing as they do huge amounts of code that never even executes.
For components that can be edited in the Object Inspector, the difference between public and published is more significant. As you say, this is how a component determines which properties are visible in the Object Inspector. Some properties should be visible there, others not. User "TLama" gives fine examples of properties that need to be public, but should not be editable in the Object Inspector: Parent, Handle and so on.
Beyond that it comes down to opinion. It's entirely up to you to decide what to do.
Destructors in Delphi are usually named "Destroy", however as far as i understand you can also
name destructors differently
have multiple destructors
Is there any reason why this was implemented this way? What are the possible use cases for differently named / multiple destructors?
In theory you can manually call different destructors to free different external resources, like breaking ref-counting loops, deleting or just closing file, etc.
Also, since the Object Pascal language does not have those magical new/delete operations, there just should be some identifier to call for disposing of the object.
I'd prefer to look at that in retrospect.
"Turbo Pascal with Objects" style objects have both - you call a "magical" Dispose procedure but explicitly specify a destructor to call, since language itself did not knew what to choose. Similarly "magic" procedure New had to be supplied with a manually selected constructor.
http://www.freepascal.org/docs-html/rtl/system/dispose.html
http://putka.acm.si/langref/turboPascal/0547.html
http://www.freepascal.org/docs-html/rtl/system/new.html
http://putka.acm.si/langref/turboPascal/04A4.html
This however violates DRY principle: compiler knows that we are calling d-tor or c-tor, but yet we have to additionally call those "New" and "Dispose" functions. In theory that probably provided to decouple memory allocation and information feeding and combine them anyway we'd like. But i don't think this feature was actually used anything wide.
Interesting that the same design is used in Apple Objective C. You 1st allocate memory for the object and after that you call a constructor for that new instance: http://en.wikipedia.org/wiki/Objective-C#Instantiation
When that model was streamlined for Delphi few decisions was made to make things more simplified (and unified). Memory [de]allocation strategy was shifted to the class level, rather than call-site. That made the redundancy of both calling "New" and named constructor very contrast. One had to be dropped.
C++/C#/Java chosen to retain a special language-level keywords for it, using overloaded functions to provide different c-tors. Perhaps that corresponds to USA style of computer languages.
However Pascal at its core has two ideas: verbosity and small vocabulary. Arguably they can be tracked in other European-school languages like Scala. If possible, the keywords should be removed from language itself and moved to external modules - libraries that you can add or remove from project. And overloaded functions were introduced much later to the language and early preference was to surely have two differently named (self-documenting) function names.
This both ideas probably caused Delphi to remove "magic" procedures and to deduce object creation/destruction at the call-site just by used function names. If you call MyVar.Destroy then compiler looks at the declaration of .Destroy and knows we are deleting the object. Similarly it knows TMyType.CreateXXX(YYY,ZZZ) is an object instanbtiation due to the way CreateXXX was declared.
To make c-tor and d-tor no-named like in C++, Delphi would have to introduce two more keywords to the language level, like those C++ new and delete. And there seems to be no clear advantage in that. At least personally i better like Delphi way.
PS. I had to add there one assumption: we are talking about real C++ and Delphi languages as they were around 1995. They only featured manual memory control for heap-allocated objects, no garbage collection and no automatic ref-counting. You could not trigger object destruction by assigning variable with nil/NULL pointer.
I'm fairly new to Delphi and have been doing all my memory management manually, but have heard references to Delphi being able to use interfaces to do reference counting and providing some memory management that way. I want to get started with that, but have a few questions.
Just generally, how do I use it. Create the interface and the class implementing it. Then anytime I need that object, have the variable actually be of the Interface type, but instantiate the object and presto? No nee to think about freeing it? No more try-finallys?
It seems very cumbersome to create a bunch of interfaces for classes that really don't need them. Any tips on auto generating those? How do I best organize that? Interface and class in the same file?
What are common pitfalls that might cause me grief? Ex: Does casting the interfaced object to the an object of its class break my reference counting? Or are there any non-obvious ways Delphi would create reference loops? (meaning besides A uses B uses C uses A)
If there are tutorials that cover any of this, that would be great, but I didn't come up with anything in my searches. Thanks.
I am currently working with a very large project that takes advantage of the "side affect" of interface reference counting for the purpose of memory management.
My own personal conclusion is that you end up with a lot of code that is overly complex for no better reason than, "I don't have to worry about calling free"
I would strongly advise against this course of action for some very basic reasons:
1) You are using a side affect that exists for the purpose of COM compatibility.
2) You are making your object footprint and efficiency heavier. Interfaces are pointers to lists of pointers.. or something along those lines.
3) Like you stated... you now have to make piles of interfaces for the sole purpose of avoiding freeing memory yourself... this causes more trouble than it's worth in my opinion.
4) Most common bug that will be a HUGE pain to debug will become when an object gets freed, before it's reference. We have special code in our own reference counting to try and test for this problem before software goes out the door.
Now to answer your questions.
1) Given TFoo and interface IFoo you can have a method like the following
function GetFoo: IFoo;
begin
Result := (TFoo.Create as IFoo);
end;
...and presto, you don't need the finally to free it.
2) Yes like I said, you think it's a great idea, but it turns into a huge pain in the bupkis
3) 2 problems.
A) you have Object1.Interface2 and Object2.Interface1... these objects will never be freed due to the circular reference
B) Freeing the object before all the references are released, I cannot stress how dificult these bugs are to track down...
The most common complaint leading to the desire for "automatic garbage collection" in Delphi is the way that even short-lived temporary objects have to be disposed of manually and that you have to write a fair amount of "boiler-plate" code to ensure that this takes place when exceptions occur.
For example, creating a TStringList for some temporary sorting or other algorithmic purpose within a procedure:
procedure SomeStringsOperation(const aStrings: TStrings);
var
list: TStringList;
begin
list := TStringList.Create;
try
:
// do some work with "list"
:
finally
list.Free;
end;
end;
As you mentioned, objects that implement the COM protocol of reference counted lifetime management avoid this by cleaning themselves up when all references to them have been released.
But since TStringList isn't a COM object, you cannot enjoy the convenience this offers.
Fortunately there is a way to use COM reference counting to take care of these things without have to create all new, COM versions of the classes you wish to use. You don't even need to switch to an entirely COM based model.
I created a very simple utility class to allow me to "wrap" ANY object inside a lightweight COM container specifically for the purpose of getting this automatic cleanup behaiour. Using this technique you can replace the above example with:
procedure SomeStringsOperation(const aStrings: TStrings);
var
list: TStringList;
begin
AutoFree(#list);
list := TStringList.Create;
:
// do some work with "list"
:
end;
The AutoFree() function call creates an "anonymous" interfaced object that is Release()'d in the exit code generated by the compiler for the procedure. This autofree object is passed a pointer to the variable that references the object you wish to be free'd. Among other things this allows us to use the AutoFree() function as a pseudo-"declaration", placing any and ALL AutoFree() calls at the top of the method, as close as possible to the variable declarations that they reference, before we have even created any objects.
Full details of the implementation, including source code and further examples, are on my blog in this post.
The memory management of interfaces is done through implementation of _AddRef and _Release which are implemented by TInterfacedObject.
In general using interfaces to make memory management less cumbersome can be a nice idea, but you need to take care of these things:
Make sure the classes that implement interfaces are derived from TInterfacedObject or roll your own ancestor class that provides good implementations for _AddRef and _Release
Use either/or: so either user interfaces references, or use object instance references, don't mix them. That can be problematic when implementing interfaces in components (as those derive from TComponent, not TInterfacedObject)
Don't go the TInterfacedComponent way as that mixes Owner based memory management and _AddRef/_Release based memory management
Watch circular interface references (you can go around implementing "weak interface references" mentioned here and implemented here)
You need to maintain extra code as you need to define interfaces for the parts your classes that you want to expose, and keep those two in sync (you could Model Maker Code Explorer for this; it allows you to extract interfaces and in general boost your development because it manages the interface/implementation parts of code in single-actions)
You need some extra plumbing to create instances of the underlying classes. You can use the factory pattern for that.
That is not always effectively, but does answer a few of your underlying questions.
Shortest possible answer: The default delphi memory model is that owners free the objects they own. All other references are weak references and must let go before the owner does. "Sharing" an object that has a lifetime shorter than the entire lifetime of the app is rarely done. Reference counting is rarely done, and when it is done, it is only done by experts, or else it adds more bugs and crashes than it solves.
Learn idiomatic delphi style and try to imitate it, don't fight the grain. Sadly, people think that "program against interfaces, not implementations" means "Use IUnknown everywhere". That's not true. I recommend you don't use COM IUnknown interfaces, and use abstract base classes instead. The only thing you can't do is implement two abstract base classes in a single class, and the need for that is rare.
Update: I've recently found it helpful to use COM Interfaces (IUnknown based) to help me separate out my model and controller implementations from my UI classes. So I do find using IUnknown based interfaces useful. But there is not a lot of documentation and prior art out there to base your efforts on. I'd like to see a "cookbook" style recipe that lays all this out for people, so they can work without the usual problem of combining interface and non-interface based lifetime management, and all the trouble that comes while you get used to that extra complexity.
Switching to interfaces only for avoiding manual Free's is senseless. Little economy in Free/try-finally lines will hardly compensate the necessity of declaring both g/setters and properties in the interface not mentioning the necessity of keeping the intf/class declarations in sync. Interfaces also bring performance loss due to implicit finalize code and reference counting. If performance is not the main point and all you want to achieve is autofreeing, I'd recommend using some universal interface wrappers like the one Deltics suggested.
I have used Delphi classes for a while now but never really got into using interfaces. I already have read a bit about them but want to learn more.
I would like to hear which pros and cons you have encountered when using interfaces in Delphi regarding coding, performance, maintainability, code clearness, layer separation and generally speaking any regard you can think of.
All I can think of for now:
Pros:
Clear separation between interface and implementation
Reduced unit dependencies
Multiple inheritance
Reference counting (if desired, can be disabled)
Cons:
Class and interface references cannot be mixed (at least with reference counting)
Getter and setter functions required for all properties
Reference counting does not work with circular references
Debugging difficulties (thanks to gabr and Warren for pointing that out)
Adding to the answers few more advantages:
Use interfaces to represent the behavior and each implementation of a behavior will implement the interface.
API Publishing: Interfaces are great to use when publishing APIs. You can publishing an interface without giving out the actual implementation. So you are free to make internal structural changes without causing any problems to the clients.
All I say is that interfaces WITHOUT reference counting are VERY HIGH on my wishlist for delphi!!!
--> The real use of interfaces is the declaration of an interface. Not the ability for reference counting!
There are some SUBTLE downsides to interfaces that I don't know if people consider when using them:
Debugging becomes more difficult. I have seen a lot of strange difficulties stepping into interfaced method calls, in the debugger.
Interfaces in Delphi come with IUnknown semantics, if you like it or not, you'r stuck with reference counting being a supported interface. And, thus, with any interfaces created in Delphi's world, you have to be sure you handle reference counting correctly, and if you don't, you'll end up with leaks. When you want to avoid reference counting, your only choice is to override addref/decref and don't actually free anything, but this is not without its own problems. I find that the more heavily interface-laden codebases have some of the hardest-to-find access violations, and memory leaks, and this is, I think because it is very difficult to combine the refcount semantics, and the default delphi semantics (owner frees objects, and nobody else does, and most objects live for the entire life of their parents.).
Badly-done implementations using Interfaces can contribute some nasty code-smells. For example, Interfaces defined in the same unit that defines the initial concrete implementation of a class, add all the weight of interfaces, without really providing proper separation between the users of the interfaces and the implementors. I know this isn't a problem with interfaces themselves, but more of a quibble with those who write interface-based code. Please put your interface declarations in units that only have those interface declarations in them, and avoid unit-to-unit dependency hell caused by glomming your interface declarations into the same units as your implementor classes.
I mostly use interfaces when I want objects with different ancestry to offer a common service. The best example I can think of from my own experience is an interface called IClipboard:
IClipboard = interface
function CopyAvailable: Boolean;
function PasteAvailable(const Value: string): Boolean;
function CutAvailable: Boolean;
function SelectAllAvailable: Boolean;
procedure Copy;
procedure Paste(const Value: string);
procedure Cut;
procedure SelectAll;
end;
I have a bunch of custom controls derived from standard VCL controls. They each implement this interface. When a clipboard operation reaches one of my forms it looks to see if the active control supports this interface and, if so, dispatches the appropriate method.
For a very simple interface you can do this with an of object event handler, but once it gets sufficiently complex an interface works well. In fact I think that is a very good analogue. Use an interface where you a single of object event won't fit the functionality.
Interfaces solves a certain kind of issues. The primary function is to... well, ...define interfaces. To distinguish between definition and implementation.
When you want to specify or check if a class supports a set of methods - use interfaces.
You cannot do that in any other way.
(If all classes inherits from the same base class, then an abstract class will define the interface. But when you are dealing with different class hierarchies, you need interfaces to define the methods thy have in common...)
Extra note on
Cons: Performance
I think many people are too blithely dismissing the performance penalty of interfaces. (Not that I don't like and use interfaces but you should be aware of what you are getting into). Interfaces can be expensive not just for the _AddRef / _Release hit (even if you are just returning -1) but also that properties are REQUIRED to have a Get method. In my experience, most properties in a class have direct access for the read accessor (e.g., propery Prop1: Integer read FProp1 write SetProp1). Changing that direct, no penalty access to a function call can be significant hit on your speed (especially when you start adding 10s of property calls inside a loop.
For example, a simple loop using a class
for i := 0 to 99 do
begin
j := (MyClass.Prop1 + MyClass.Prop2 + MyClass.Prop3) / MyClass.Prop4;
MyClass.Update;
// do something with j
end;
goes from 0 function calls to 400 function calls when the class becomes an interface. Add more properties in that loop and it quickly gets worse.
The _AddRef / _Release penalty you can ameliorate with some tips (I am sure there are other tips. This is off the top of my head):
Use WITH or assign to a temp variable to only incur the penalty of one _AddRef / _Release per code block
Always pass interfaces using const keyword into a function (otherwise, you get an extra _AddRef / _Release occurs every time that function is called.
The only case when we had to use interfaces (besides COM/ActiveX stuff) was when we needed multiple inheritance and interfaces were the only way to get it. In several other cases when we attempted to use interfaces, we had various kinds of problems, mainly with reference counting (when the object was accessed both as a class instance and via interface).
So my advice would be to use them only when you know that you need them, not when you think that it can make your life easier in some aspect.
Update: As David reminded, with interfaces you get multiple inheritance of interfaces only, not of implementation. But that was fine for our needs.
Beyond what others already listed, a big pro of interfaces is the ability of aggregating them.
I wrote a blog post on that topic a while ago which can be found here: http://www.nexusdb.com/support/index.php?q=intf-aggregation (tl;dr: you can have multiple objects each implementing an interface and then assemble them into an aggregate which to the outside world looks like a single object implementing all these interfaces)
You might also want to have a look at the "Interface Fundamentals" and "Advanced Interface Usage and Patterns" posts linked there.
Just recently, probably because I've been maintaining some old code, I've started to look at how / why I do things. As you do.
Most of my Delphi programming has been picked up in house, or from examples scattered across the web or manuals. And in some things are done just because "that's how I do it"
What I'm currently wondering about is Declaration, of variables, procedures, functions, etc.
When I am working with a form, I will place all my procedures and functions under public or private. Whilst I will try to avoid global vars and constants will generally go under var or const, either in the interface or implementation, depending on where they need to be called (occasionally though they will go in public / private)
Otherwise, if its just a unit I will declare the procedure in the interface and use in the implementation. Some of the code I've been maintaining recently has no interface declaration but instead has everything properly ordered with calls after procedures...
Is there a correct way to do this? Are there rules of what should / should not go in the class? Or is it a style / when you started thing?
Edit to add
My question is not about whether a declaration of a procedure goes in private/public but whether all declarations in a TForm Unit should go in one of these. Similarly should var / const be in one or the other?
Further clarification
I understand that not declaring in interface, or declaring in public/private/etc affects the visibility of procedures/functions to other units in my applicaiton.
The core of my question is why would i not want to declare? - especially when working in a form/unit when placing in private is much more explicit that the thing declared is not available to other units...
Cheers
Dan
Everything that can have a different value depending on the concrete instance belongs to the class, i.e.
TDog = class
strict private
FColor : TColor;
FName : String;
public
property Color : TColor read FColor write FColor;
property Name : String read FName write FName;
end;
Color and name are clearly attributes of each dog (and each dog will have other values here).
General rules:
Fields belong in private (visible in this class and in this unit) or strict private (visible only in this class)
If you need access to fields from other classes, create a public property. This gives you the freedom to change the simple field access to a more sophisticated getter / setter method lateron without changing the interface of your class.
Everything should be as local as possible. If private is enough, there's no need to make it protected (visible in subclasses too). And only make those things public that you really need from the outside.
Forms: only those things that you want to be stored in the DFM file should be published.
Put as much as you can in the implementation section and as little as you can in the interface section. This is also true for uses clauses.
You might be confusing the term global variable. If it's declared in a class it's not a global variable (even if declared public). Global variables (which you correctly consider good to avoid) always go in a var section either in the interface or the implementation section (which is preferrable following the general rules above)
The question seems to deal with scope. In other words, how easily accessible things can or should be.
As a general guideline, you want to reduce the scope of things as much as possible but still keep them accessible enough to be reused. The reason for this is:
that as your system grows and becomes more complex, the things that have are larger scope are more easily accessible.
as a result, they are more likely to be reused in an uncontrolled fashion.
(sounds great) but the problem comes when you want to make changes, and many things use that which you want to change...
it becomes far more difficult to make your changes without breaking something else.
Having said that, there is also a distinction between data (variables, constants, class fields, record attributes) and routines (functions, procedures, methods on classes). You'll want to apply the guidelines far more strictly to data because 'strange use' of data could interfere with some of your routines in highly unexpected and hard to debug ways.
Another thing to bear in mind is the special distinction between global variables and class fields or record attributes:
using global variables there is only one 'value' (term used loosely) for the entire application.
using class fields or record attributes, each new instance of the class or record has its own values independent of other instances.
This does seem to imply that you could use some form of global whenever your application only needs one thing. However, as alluded to earlier: this is not the only reason to avoid globals.
Personally I even tend to avoid global routines.
I'm frequently discovering that things that seemed okay declared global are not as universal as first thought. (E.g. Delphi VCL declares a global Screen object, I work on 2 screens; and many of our clients use 4 to 6.)
I also find it useful to associate routines that could have been global with specific classes as class methods. It generally makes it easier to understand the code.
So listing these 'locations' from largest scope to smallest, you would generally strive to pick locations lower down in the list (especially for data).
interface global
implementation global
interface threadvar
implementation threadvar
published (Note I don't really consider this to be a scope identifier; it's really public scope; "and includes RTTI information" - theoretically, it would be useful to also mark some private attributes as "include RTTI".)
public
protected
private
strict private
local variable
I must confess: what I have presented here is most certainly an over-simplification. It is one thing to know the goals, another to actually implement them. There is a balancing act between encapsulation (hiding things away) and exposing controlled interfaces to achieve high levels of re-usability.
The techniques to successfully balance these needs fall into a category of far more complicated (and sometimes even contentious) questions on system design. A poor design is likely to induce one to expose 'too much' with 'too large' a scope, and (perhaps paradoxically) also reduce re-usability.