From: Arnout E. <no...@bz...> - 2011-04-09 15:15:38
|
Hi, I think the way inheritence and upcasting are done in Notion is a bit inconsistent and confusing, and would like to propose a change. Classes in notion's OO are declared like this: DECLCLASS(WScreen){ WMPlex mplex; int id; ... } Basically this introduces a 'WScreen' type, and the first element of the struct holding its data is the supertype, in this case 'WMPlex'. In code, whenever you have a WScreen* and need a WMPlex, we use either casts: mplex_map((WMPlex*)scr); ((WWindow *)(rw->scr))->win=None; or look at the first field: mplex_map(&scr->mplex); rw->scr.mplex.win.win=None; There are advantages and disadvantages to both calling conventions: the former variation has the advantage that it is usually fairly short, and it's immediately clear that the called function operates on a WMPlex/WWindow. It has the disadvantage that you have to use a typecast, which the compiler cannot verify is correct. The latter variation has the advantage that it's type-safe. The disadvantage is that it is not immediately clear whether scr 'is an mplex' or 'has an mplex'. The second example makes this extra clear: the mplex 'is a' win which 'has a' win. To mitigate the latter, I think it'd be neat to adopt the convention to always call the first field 'super'. This will lead to: mplex_map(&scr->super); rw->scr.super.super.win=None; The way I look at it now, we should pick one of the following conventions: (a) always use typecasts, never use the first field of the struct explicitly (b) always use the first field of the struct (c) use the first field of the struct if we need the direct parent, use a typecast when you need to go higher up the hierarchy. in cases 'b' and 'c', we should decide whether to rename the first field to 'super'. What would you guys prefer? I'm still undecided - imho either of those choices is better than the current inconsistency though ;) Kind regards, Arnout |