Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8265159
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 8, 20262026-06-08T04:42:07+00:00 2026-06-08T04:42:07+00:00

I have two classes: one base class an one derived class The base class

  • 0

I have two classes: one base class an one derived class
The base class defines a virtual method with a parameter:

function ToName(MsgIfNil:string=''); virtual;

The derived class redefines the method:

function ToName(MsgIfNil:string=''); reintroduce;

The implementation of both methods is similar to this code:

function TBaseClass.ToName(MsgIfNil:string)
begin
  if (Self=nil) then
    Result := MsgIfNil
  else
    Result := Self.SomeProperty;
end;

The issue is that:

1) If I do not reintroduce the method in the derived class, but use the regular override keyword, any call to this method triggers an access violation

2) When I call the method from an object being nil, and the presumed class of the objet is TBaseObject, it crashes (AV) instead of calling the base virtual method

If no parameter is defined in the method, the right method is called, without any AV. It works well even if the method in the derived class is overriden.

Note that the above solution works well with objects of any class derived from TBaseClass

How can I define a virtual method that can be called with Self=nil, can be virtual and use parameters?

I certainly must enhance my understanding of internal virtual method call plumbering…

Note: Calling on a nil object is legitimate in my use cases. It is not used to hide exceptions, but to report on non linked objects.
Example: myEdit.Text := APerson.Manager.ToName(‘No manager defined’);

Thanks for any advise on a proper solution

Using Delphi 2010 with upd5


Edit: Adding a more complete example of code that triggers an AV

TBaseClass = class(TObject)
private
  FMyName: string;
public
  property MyName: string read FMyName;
  function ToName(MsgIfNil:string=''):string; virtual;
end;

TDerivedClass = class(TBaseClass)
private
  FSpecialName: string;
public
  property SpecialName:string read FSpecialName;
  function ToName(MsgIfNil:string=''):string; reintroduce;
end;

TBaseClass.ToName(MsgIfNil:string):string;
begin
   if (Self=nil) then
     Result := MsgIfNil
   else
     Result := MyName;
end;

TDerivedClass.ToName(MsgIfNil:string):string;
begin
  if (Self=nil) then
    Result := MsgIfNil
  else
    Result := SpecialName;
end;

// Now a sample program

var
  aPerson: TBaseClass;
  aSpecialist: TDerivedClass;

begin

aPerson := TBaseClass.Create;
aPerson.MyName := 'a person';
aSpecialist := TDerivedClass.Create;
aSpecialist.SpecialName := 'a specialist';

aSpecialist := nil; // For example sake, never do this in my use case :)
// This works here,
// but triggers an AV if ToName is marked as override instead of reintroduce
ShowMessage('Name of the specialist: '+aSpecialist.ToName('No specialist!'));

aPerson := nil;
// This triggers an AV, TBaseClass.ToName is never called
ShowMessage('Name of the person: '+aPerson.ToName('No person!'));

end;

The above code may not compile, this is only intended to be a more complete example

Takeway

I now understand that VMT is linked to the object reference and, regardless of the object class, calling a virtual method on a nil object is not possible (the object will not even look at its declared type to get the matching address of the ToName method)

I accepted hvd’s solution because it is really effective for methods that must check vs nil (only one base method to add).

Thanks for all answers,

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-08T04:42:09+00:00Added an answer on June 8, 2026 at 4:42 am

    Calling a virtual method on nil doesn’t make sense: virtual means “check the class type to see which method to call”. There is no class type, so there is no method to call.

    What you can do is create a nonvirtual method that calls a virtual method:

    // TBase
    public:
        function ToName(MsgIfNil: string = ''): string;
    protected:
        function ToNameImpl: string; virtual;
    
    // TDerived
    protected:
        function ToNameImpl: string; override;
    
    function TBase.ToName(MsgIfNil: string): string;
    begin
      if (Self=nil) then
        Result := MsgIfNil
      else
        Result := ToNameImpl;
    end;
    
    function TBase.ToNameImpl: string;
    begin
      Result := MyName;
    end;
    
    function TDerived.ToNameImpl: string;
    begin
      Result := MyDerivedName;
    end;
    

    This ensures that ToNameImpl, the virtual method, is only called when Self is not nil.

    Edit: By the way, this is exactly what the nonvirtual TObject.Free does to call the virtual TObject.Destroy.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a base class, Parameter, and two derived classes: Scalar & Vector. In
I have two classes - one base class and one derived from it :
I have two classes (MVC view model) which inherits from one abstract base class.
I have two classes, one that inherits from the other. The base class is
I have two classes, a base class and a derived class. My base class
I have a two windows forms classes, a base class and a derived class.
I have two different classes deriving from one base class. They each have a
If I have a base class and two derived classes, and I want to
I have two classes, Base and Derived . I provide a function that applies
I have two classes like this (simplified and renamed): class Base { public: virtual

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.