[fpc-pascal] multiple inheritence

David Emerson dle3ab at angelbase.com
Sat Oct 3 09:24:09 CEST 2009


Hi all,

I've been reading about multiple inheritance in the list archives, and 
from what I gather, it is only supported through a combination 
of "interfaces" and classes; one cannot inherit from two classes.

As far as I can tell, interface types do not allow implemented virtual 
methods -- only abstract ones.

Given these constraints, I'm wondering how to go about creating my 
types. Perhaps what I want to do is not possible, or perhaps I just 
don't know how? Here is the plain english description:

I'd like to create a "double-list" type, which maintains two parallel 
lists containing the same elements: one sorted, one unsorted. The 
reason to have both: sorted -> fast search; unsorted -> sequential 
navigation through the list while elements are being added.

I created a list_base, which contains variables and methods common to 
both unsorted and sorted lists (capacity, used_length, method 
increment_capacity_counter). The sorted_list has a "find" method, 
whereas the unsorted_list has a "next" method that increments a 
progress index.

The sorted and unsorted list types implement "add" differently, so the 
double-list would need to call both of the inherited "add" methods (or 
manually rewrite the same functionality)

I can't figure out how to do it legally.

For those who like code, here's a class description that uses illegal 
multiple class inheritance ;)   There are a few notes below.

type

class_type = class
  end;

t_list_base = class (TObject)
  private
    f_capacity, f_used_length : longint;
    f_cs : TRTLCriticalSection;
    function inc_capacity : boolean; virtual;
    function grow_if_needed : boolean; virtual;	abstract;
    function internal_add (const class_in : class_type) : boolean;
        virtual; abstract;
  public
    property count : longint read f_used_length;
  end;

t_unsorted_list = class (t_list_frame)
  private
    f_ulist : array of class_type; // ulist = unsorted list
    f_next_index : longint;
    function get_pending_count : longint;  // used_length - next_index
    function grow_if_needed : boolean; override;
    function internal_add (const class_in : class_type) : boolean;
        override;
  public
    function next (out class_out : class_type) : boolean; virtual;
    property pending_count : longint read get_pending_count;
  end;

t_sorted_list = class (t_list_frame)
  private
    f_slist : array of class_type; // slist = sorted list
    function grow_if_needed : boolean; override;
    function internal_add (const class_in : class_type) : boolean;
        override;
  public
    function find (const target : longint) : bsearch_res_type; virtual;
  end;

t_double_list = class (t_unsorted_list, t_sorted_list)
  private
    function grow_if_needed : boolean; override;
    function internal_add (const class_in : class_type) : boolean;
        override;
  end;




small notes / questions:

class_type = class
  end;  // is this equivalent to TObject?

t_list_base = class (TObject) // is TPersistent or no ancestor better?
regarding inc_capacity:
- if f_used_length<f_capacity then inc_capacity just returns false
- virtual so that other memory management algorithms can override it.
regarding grow_if_needed:
- will setlength on the list, but list_base has no list! so abstract
regarding internal_add:
- maybe it's best not to list this abstract here, as doing so sepersedes 
the possibility of using list_base for, e.g., a list of longints. Or 
perhaps this is a good place to use a variant type?




More information about the fpc-pascal mailing list