From maintainers-request at octave dot org Wed Nov 16 10:36:40 2005 Subject: Re: Octave_value class hierachy From: "John W. Eaton" To: Jens Ruecknagel Cc: octave-maintainers-list Date: Wed, 16 Nov 2005 11:36:11 -0500 On 24-Apr-2004, Jens Ruecknagel wrote: | Thanks for you answer. | | your foo.cc is exactly what i was thinking about except one line: | | diff foo.orig.cc foo.cc | 32c32 | < value fun (void) const | --- | > virtual value fun (void) const | | in foo you cannot do what you can do in bar: | value crash = type_one () ; // you know I cannot write "value crash( | type_one())" because in c++ this is a forward declaration of a function | crash | | and in octave_value you can write: | | octave_value crash (octave_scalar(1)); | | Because the of the union {count, rep} the copy constructor cannot find | out whether it is a value or a base_value. | | Or because of base_value : public value and base_value is NOT a value, | value is just a a pointer to a base_value. | Or maybe it is even a proxy [Gama, Helm, Johnson, Vlissidis, Design | Patterns] to a base_value. If one wants, they may both (value and | base_value) share the same interface: inherit both from the abstract | class value_interface. | | But what the big deal: octave_value works: just don't call functions of | octave_base_value or its descendants. But it took me one week to find | this out. I'd like to revisit this topic now. For extra context, see http://www.octave.org/mailing-lists/octave-maintainers/2004/437 http://www.octave.org/mailing-lists/octave-maintainers/2004/443 I think your suggestion is good, and could simplify the implementation of the octave_value classes a bit. We would need to make the following changes: * octave_value::rep becomes a pointer to octave_base_value instead of octave_value * The octave_base_value class is no longer derived from octave_value. * All other value classes must be derived from octave_base_value (I think this is already true, but it would become a requirement). * Functions in the octave_value class would not need to be declared virtual, but the functions in octave_base_value would be virtual. * In addition to changing the type of octave_value::rep, we would also have typedef octave_base_value * (*type_conv_fcn) (const octave_value&); octave_value (octave_base_value *new_rep, int count = 1); octave_base_value *clone (void) const; octave_base_value *empty_clone (void) const; octave_base_value *try_narrowing_conversion (void); octave_base_value *internal_rep (void) const; in the octave_value class instead of typedef octave_value * (*type_conv_fcn) (const octave_value&); octave_value (octave_value *new_rep, int count = 1); virtual octave_value *clone (void) const; virtual octave_value *empty_clone (void) const; virtual octave_value *try_narrowing_conversion (void); octave_value *internal_rep (void) const; and the nil_rep function could be moved to the octave_base_value class. These changes would affect all derived types, but should only require a change in the declaration, with no change in the way the functions actually work. * There would be no need for the octave_xvalue struct (which is just confusing anyway). * The rep could be assumed to always be non-null. * As Jens suggested, we could move count to the octave_base_value class. Comments? jwe