How to avoid 'explicit constructor call not allowed' error - mql4

Does somebody know, how to avoid the next compilation error?
explicit constructor call not allowed
Is it possible to call a superclass-constructor inside a children class?
Thanks!

Related

Delphi Class Helper RTTI GetMethod

Lets say I have a sample class helper
TSampleClassHelper = class helper for TSampleClass
public
procedure SomeHelper;
end;
I do the following:
var
obj :TSampleClass;
begin
obj:=TSampleClass.Create;
obj.SomeHelper;
end;
and this works as expected.
But how can I use RTTI to invoke the helper method instead? The following does not seem to work, GetMethod returns nil.
var
obj :TSampleClass;
ctx :TRTTIContext;
rtype :TRTTIType;
rmethod :TRTTIMethod;
begin
obj:=TSampleClass.Create;
rtype:=ctx.GetType(obj.ClassType);
rmethod:=rtype.GetMethod('SomeHelper'); // rmethod is nil !
end;
So does RTTI not work for methods defined in class helpers? Is there anyway around this?
Thanks.
The reason your code returns a nil method is that the object's type does not contain a method named SomeHelper. The type that contains that method is the helper type.
So, you could write this which will return a non-nil method:
obj:=TSampleClass.Create;
rtype:=ctx.GetType(TypeInfo(TSampleClassHelper));
rmethod:=rtype.GetMethod('SomeHelper');
Of course, you should immediately see the first problem, namely the use of a compile time specified type, TSampleClassHelper. Can we use RTTI to discover TSampleClassHelper at run time based on the type of the instance? No we cannot, as I will explain below.
Even if we put that to one side, as far as I can see, there's no way to invoke the method using RTTI. If you call rmethod.Invoke(obj, []) then the code in TRttiInstanceMethodEx.DispatchInvoke blocks an attempt to call the helper method. It blocks it because it decrees that the type of the instance is not compatible with the class of the method. The pertinent code is:
if (cls <> nil) and not cls.InheritsFrom(TRttiInstanceType(Parent).MetaclassType) then
raise EInvalidCast.CreateRes(#SInvalidCast);
Well, you can obtain the code address of the helper method with rmethod.CodeAddress but you'll need to find some other way to invoke that method. It's easy enough to cast it to a method with the appropriate signature and invoke it. But why bother with rmethod.CodeAddress in any case? Why not use TSomeHelperClass.SomeMethod and cut RTTI out of the loop?
Discussion
Helper resolution is performed statically based on the active helper at the point of compilation. Once you attempt to invoke a helper method using RTTI there is no active helper. You've long since finished compiling. So you have to decide which helper class to use. At which point, you don't need RTTI.
The fundamental issue here is that class helper method resolution is fundamentally a static process performed using the context of the compiler. Since there is not compiler context at run time, class helper method resolution cannot be performed using RTTI.
For more insight into this have a read of Allen Bauer's answer here: Find all Class Helpers in Delphi at runtime using RTTI?

Calling Virtual Function in FormCreate

I am playing with an already existing code. I have a base class form where i introduce a virtual function and calling the function in FormCreate. In some derived class i override the function and have my own implementation. But when i am executing the application i am getting "EAbstract error". I dont know why i am getting this exception. When i debugged it is FormCreate is executing well for some forms but for some other forms i am getting this exception. I am new to Delphi so ignore my ignorance. Thanks.
Somewhere in your program is a class which declares an abstract virtual:
procedure Foo; virtual; abstract;
And your program instantiates a class that does not override this abstract method, and then calls the method. When this method is called, an EAbstractError exception is raised.
The abstract method is not necessarily declared in code that you wrote. For example, perhaps you instantiated a TStrings class:
Strings := TStrings.Create;
when you meant to write
Strings := TStringList.Create;
Subsequent method calls on the TStrings instance will lead to abstract errors. Remember that TStrings is an abstract class full of abstract methods.
With many patterns of class instantiation your code would lead to a compiler warning. The compiler will warn that you are instantiating a class that contains abstract methods. If your mistake is as suggested above, then the compiler warnings will locate the error for you. I cannot stress enough the importance of listening to the compiler's warnings.
However, if the abstract class in question is a form, then the compiler will not be able to warn if you are using Application.CreateForm to instantiate it.
If your code declares the abstract method, then you can find the problem readily by performing a search (Find in Files) for the uses of abstract. If that does not help, and there are no compiler warnings, then configure the debugger to break on exceptions and then take a look at the call stack when the program breaks on the exception.

Handle create controller exception in MVC3

I have a controller that takes multiple arguments and I am using Unity to create an instance of that controller. The problem is that under certain circumstances Unity is not able to build all of the objects that are needed for my constructor so it throws an Exception.
[MissingMethodException: No parameterless constructor defined for this object.]
How do I handle this error and show a custom error page to the user?
Don't handle that error, either create parameterless constructors for said objects that are instantiated, or don't create them in the constructor. Handling those exceptions would just be masking the issue.

How do I avoid an "abstract error" with a TCustomGrid descendant?

Whats the minimum I have to do to descend a new control from TCustomGrid, and get it on a form in the IDE without getting 'Abstract Error' within the IDE?
I have tried everything for days, but Im a bit of a delphi noob atm, zero percent success with TCustomGrid :(
If someone could help me out just getting a basic descendant of TCustomGrid which does nothing but implement the base TCustomGrid behavious it would be much a appreciated. Thanks.
Edit - I know how to do the basics of creating controls, I just cant do it with TCustomGrid
"Abstract Error" usually means that there are virtual abstract functions you'll have to implement to make the class work. For TCustomGrid, this should be the DrawCell method, as you can see here.
For a complete detailed example on how to build an own grid based on TCustomGrid, see this tutorial.
You only get abstract errors if you neglect to override and provide an implementation for a method that was declared virtual abstract in either TCustomGrid or any of its ancestors.
So the solution would be to find all of these (use ctrl-click on the class names to get from ancestor to ancestor) and provide an override. Start with an empty implementation of your overrides. That may cause other errors and broken/unexpected behaviour, but should get you past the abstract errors.

Delphi 6: Force compiler error on missing abstract class methods?

I'm using Delphi Pro 6. Right now, the only way to know if a class is missing a base class abstract method is to wait for the IDE to emit a "constructing instance of {derived class} containing abstract method {base class.abstract method name}" warning or to wait for a runtime Abstract Error method when an attempt to call the missing method is made. The former isn't sufficient since it only finds warnings for those derived classes actually constructed in the current project. The latter is just plain painful.
It would be so much better if Delphi output a fatal warning for all classes that do not declare/implement a base class abstract method immediately. Does anyone know a way to set this up or a plug-in that does this?
Thanks.
I've found the simplest way to do this is to add a section in the unit initialization area using a conditional define that creates an instance of each class that you think shouldn't have any abstract methods:
{$IFDEF CheckAbstracts}
initialization
TSubclass1.Create(params);
TAbstractClass1.Create(params); // Gives constructing instance of {derived class} containing abstract method warning
{$ENDIF}
Compile with the CheckAbstracts conditional, and you will get warnings whenever you have an incompletely implemented class.
A class containing abstract methods is only dangerous if you instantiate the class, so Delphi's warning is spot-on. You only get the abstract-error run time exception if you ignored at least one "instantiating class with abstract methods".
It's valid to not implement these methods. You might intend to implement the abstract method in yet another subtype.
A later version of Delphi/Win32 (I don't remember which) introduced formal abstract classes, which make it clear when you do and do not intend to instantiate the type. If you're rigorous about using this, the feature you request would then make sense. But for D6 it is not clear.

Resources