You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@axis.apache.org by "Senaka Fernando (JIRA)" <ji...@apache.org> on 2007/12/22 14:07:44 UTC

[jira] Commented: (AXIS2C-255) Improvements to inheritance model

    [ https://issues.apache.org/jira/browse/AXIS2C-255?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#action_12554113 ] 

Senaka Fernando commented on AXIS2C-255:
----------------------------------------

Hi Samisa,

I think this block of code seems to be too complicated and highly coupled and involves a great deal of effort if one had to do some modification on a later date. However, why can't we define axiom_element_t as,

typedef struct axiom_element
{
    axiom_node_t *base;
    ....
} axiom_element_t;

Thus, it is a matter of casting an element to a node, if we were to use the node. Isn't this more or less similar to inheritance in C++ and Java?

However, we need to be clear on whether this kind of improvement needs to be added at a major release such as a 2.0.0 or whether it could be added at a minor release such as, 1.2.0?

Regards,
Senaka

> Improvements to inheritance model
> ---------------------------------
>
>                 Key: AXIS2C-255
>                 URL: https://issues.apache.org/jira/browse/AXIS2C-255
>             Project: Axis2-C
>          Issue Type: Improvement
>    Affects Versions: Current (Nightly)
>            Reporter: Samisa Abeysinghe
>
> In Axiom and a few others places, we have a relationship between types
> which in Java is inheritance.  For example, element and
> processing_instruction both inherit from node.  However, in C there is
> no inheritance relationship. Instead there are two distinct objects.
> For example, instead of having an element which *is a* node, for each
> element object there is a separate node object and the node object
> points to the element object.  This is confusing and inefficient. This
> is essentially doubling the number of allocations and adding an extra
> layer of indirection.
> It is a little bit tricky to do OO inheritance in straight C (there's a
> reason why people use C++...), but it is doable.  Here's some sample
> code:
> /* a.h */
> struct a;
> struct a_ops {
>   void (*destroy)(struct a *);
>   void (*x)(struct a *);
> };
> struct a {
>   const struct a_ops *ops;
> };
> #define A_DESTROY(pa) ((pa)->ops->destroy(pa))
> #define A_X(pa) ((pa)->ops->x(pa))
> /* b.h */
> struct b;
> struct b_ops {
>   struct a_ops base;
>   void (*y)(struct b *);
> };
> struct b {
>   const struct b_ops *ops;
> };
> /* cast a struct pb * to a struct pa * */
> #ifdef __GNUC__
> /* use an inline where available for proper type-checking */
> inline struct a *B_BASE(struct b *pb)
> {
>   return (struct a *)pb;
> }
> #else
> #define B_BASE(pb) ((struct a *)(pb))
> #endif
> #define B_DESTROY(pb) A_DESTROY(B_BASE(pb))
> #define B_X(pb) A_X(B_BASE(pb))
> #define B_Y(pb) ((pb)->ops->y(pb))
> /* a.c */
> struct a_impl {
>   struct a iface;
>   int m;
> };
> /* note that if the class can be inherited from, these really need to be
> non-static and declared in a header file */
> void a_destroy(struct a *a);
> void a_x(struct a *a);  
> static const struct a_ops a_ops = {
>   a_destroy,
>   a_x
> };
> void a_init(struct a_impl *a)
> {
>   a->m = 17;
> }
> struct a *create_a()
> {
>   struct a_impl *a = malloc(sizeof(struct a_impl));
>   a->iface.ops = &a_ops;
>   /* factor out initialization into function so it can be called
>      by superclasses */
>   a_init(a);
>   return &a->iface;
> }
> void a_destroy(struct a *a)
> {
>   free(a);
> }
> void a_x(struct a *a)
> {
>   ((struct a_impl *)a)->m = 42;
> }
> /* b.c */
> struct b_impl {
>   struct a_impl base;
>   int n;
> };
> void b_destroy(struct a *);
> void b_x(struct a *);
> void b_y(struct b *);
> static const struct b_ops b_ops = {
>   {
>     b_destroy,
>     b_x
>   },
>   b_y
> };
> void b_init(struct b_impl *b)
> {
>   a_init(&b->base);
>   b->n = 57;
> }
> struct b *create_b()
> {
>   struct b_impl *b = malloc(sizeof(struct b_impl));
>   b->base.iface.ops = &b_ops.base;
>   b_init(b);
>   /* note we have to cast here, unlike in the no inheritance case */
>   return (struct b *)b;
> }
> void b_destroy(struct a *a)
> {
>   /* clean up our stuff first */
>   /* then call base destructor */
>   a_destroy(a);
> }
> void b_x(struct a *a)
> {
>   struct b_impl *impl = (struct b_impl *)a;
>   /* for example */
>   impl->base.m = 42;
>   impl->n = 43;
> }
> void b_y(struct b *b)
> {
> }
> /* foo.c */
> void foo()
> {
>   struct a *a;
>   struct b *b;
>   b = create_b();
>   B_X(b);
>   B_Y(b);
>   B_DESTROY(b);
>   a = create_a();
>   A_X(a);
>   A_DESTROY(a);
>   b = create_b();
>   a = B_BASE(b);
>   A_X(a);
>   A_DESTROY(a);
> }
> (based on comments by James)

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


---------------------------------------------------------------------
To unsubscribe, e-mail: axis-c-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-c-dev-help@ws.apache.org