Multiple Abstract (contd)

Burak Serdar bserdar@nc.rr.com
Thu Sep 11 03:08:00 GMT 2003


I don't know what the standard mandates in terms of class layout in 
multiple inheritance, so I can't comment on that. Nevertheless, you can 
get rid the offset addition by introducing a class derived from base_1 
and base_2, and deriving C from that composite class. The composite has 
to be known, and C can still be declared using the type_list templates. 
This way, you can at least know the base of C while *typing* the code.

Jacob Smith wrote:
> BTW, I'm trying not to stray too deeply into "how to program C++": I'm 
> wondering about implementation specifics of GCC 3.X vs. the standard.
> 
> I found the notes about virtual functions and vtables at 2.5.5, a little 
> more in 15.2/X in the standard. My question is if my solution to the 
> problem (I include my the code at the end) only works for GCC 3.3.1 (and 
> similar) or if there is further standardization of the vtable layout 
> which isn't in the Stroustrup reference or, even better, I'm missing 
> something obvious like static_cast<> etc. Basically, the layout I'm 
> seeing is this:
> class A /* virtual abstract base class*/
> class B /* virtual abstract base class*/
> class C : public A, public B /* concrete class, known only during 
> compilation, not "before" or "after" - no typedefs etc. possible */
> Layout of C
> [pointer to vtable:A, sizeof(void*)][pointer to vtable:B, 
> sizeof(void*)][data... sizeof(...)]
> Using offsets into the layout of a class is an ugly hack and I was 
> hoping for a more C++ish solution. Note that I can't get around the 
> hashing of the pointer (the actual call is for the WNDCLASS{EX} in Win32 
> using the cbWndExtra set to a pointer and a push of SetWindowLong and a 
> pop of GetWindowLong). If the answer is "that's what you get for mixing 
> old-school C with C++", that's fine. Also, note that the class type for 
> the equivalent of class C is generated at compile-time, after I'm done 
> "programming" - the type is unkown when I'm physically *typing* the code.
> -j.
> 
> Burak Serdar wrote:
> 
>> If GetHashedValue() is a function that allocates an instance of class 
>> concrete, and returns a char * (+4?), this is the correct behavior, as 
>> the type cast is not safe. The +4 offset accounts for the vtable 
>> pointer  of 'base_1', aligning a 'concrete' pointer to be a 'base_2'.
> 
> 
> 
> /* this function correctly creates an interface, given the concrete 
> class C, and the type-list of inherit types */
> template < typename T, typename type_list_T >
> T& interface ( void *ptr ) {
>   return *((T*)(ptr) + type_search<T,type_list_T>::result);
> };
> /* this is the declaration of type_search, going beyond the bounds 
> returns N for an array of size N, or "one beyond the end" value */
> template < typename search_T, typename type_list_T >
> struct type_search;    // root inherit type
> template < typename search_T >
> struct type_search< search_T, type_terminator > {                    // 
> result is based at 0
>   enum { result = 0 };
> };
> template < typename search_T, typename U >
> struct type_search< search_T, type_list<search_T,U> > {            // 
> found what we're looking for
>   enum { result = 0 };                                                  
> // result is based at 0
> };
> template < typename search_T, typename T, typename U >
> struct type_search< search_T, type_list<T,U> > {                    // 
> searching at case N
>   enum { result = 1 + type_search<search_T,U>::result };            
>       // add 1, look in tail
> };
> 
> /* defines a type-list */
> template < typename T, typename U >
> struct type_list {
>   T head;
>   U tail;
>   typedef T head_T;
>   typedef U tail_T;
>   typedef type_list<T,U> type_list_T;
> };
> /* also code to generate a class which inherits every type of a 
> type-list, sort, append, erase etc. etc. */
> 
> The type-lists are derived from the algorithms/data structures in 
> "Modern C++ Design", Andrei Alexandrescu, 2001, Addison-Wesley etc. etc.
> 
> 
> 
> 



More information about the Gcc-help mailing list