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?
