Topic: Self dependency in derivation?


Author: Srinivas Vobilisetti <Srinivas.Vobilisetti@mci.com>
Date: 1997/08/02
Raw View
Dirk Herrmann wrote:
>
> Hello everybody.
>
> The following code compiles and runs fine under gcc and as I was told
> also under Borland (which version I don't know):
>
> template <class T>
> class Base
> {
>   public:
>         T& mySelf() { return *(T*)this; }
> };
>
> class X: public Base<X>
> {
>   public:
>         void printHello() { cout << "hello "; }
> };
>
> class Y: public Base<Y>
> {
>   public:
>         void printWorld() { cout << "world"; }
> };
>
> int main()
> {
>     X x;
>     Y y;
>
>     x.mySelf().printHello();
>     y.mySelf().printWorld();
> }
>
> I wonder why this can work at all. As far as I know, the base classes
> have to be defined before you can derive from them. In the above case,
> this would mean, that Base<X> must be defined before I could derive
> X from it.
>

As long as you forward declare a class (even derived class), you can use
reference/pointer to that class. But to create objects of that class,
you need complete its definition before use.

In the program example above, you are using only reference to the
derived class while 'class T' in 'template<class T> class Base ..." acts
as forward declaration for the derived class.

Srinivas
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: george@dircon.co.uk (George Curry)
Date: 1997/07/29
Raw View
In article <33D73CE0.2EAA@ida.ing.tu-bs.de>, Dirk Herrmann
<Herrmann@ida.ing.tu-bs.de> wrote:
>Hello everybody.
>
>The following code compiles and runs fine under gcc and as I was told
>also under Borland (which version I don't know):
>
>
>template <class T>
>class Base
>{
>  public:
>        T& mySelf() { return *(T*)this; }
>};
>

I think your problem exists in your Base Class, from what I can make out
Base::mySelf needs to know the size of T when code is generated for it.  If
the compiler generates genuine inline code, it only needs to create the code
for the mySelf function, where it is used, at which point all the sizes are
known.  However if the compiler is not generating the code inline, or it is
working out the code to be generated ahead of time, it colud quite easily get
upset.  Early Microsoft compilers used to generate code for all inline
functions as real functions and delete them if not used.

The more portable way of doing this is to use pointers.

        T *mySelf() { return (T*)this; }

    x.mySelf()->printHello();
    y.mySelf()->printWorld();

This should be a lot more portable as the compiler never needs to know the
size of anything.  I do however find your program a little bizarre, what are
you really trying to achieve with this?

>
>class X: public Base<X>
>{
>  public:
>        void printHello() { cout << "hello "; }
>};
>
>
>class Y: public Base<Y>
>{
>  public:
>        void printWorld() { cout << "world"; }
>};
>
>
>int main()
>{
>    X x;
>    Y y;
>
>    x.mySelf().printHello();
>    y.mySelf().printWorld();
>}
>

George Curry
george@dircon.co.uk
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: Dirk Herrmann <Herrmann@ida.ing.tu-bs.de>
Date: 1997/07/25
Raw View
Hello everybody.

The following code compiles and runs fine under gcc and as I was told
also under Borland (which version I don't know):


template <class T>
class Base
{
  public:
 T& mySelf() { return *(T*)this; }
};


class X: public Base<X>
{
  public:
 void printHello() { cout << "hello "; }
};


class Y: public Base<Y>
{
  public:
 void printWorld() { cout << "world"; }
};


int main()
{
    X x;
    Y y;

    x.mySelf().printHello();
    y.mySelf().printWorld();
}

I wonder why this can work at all. As far as I know, the base classes
have to be defined before you can derive from them. In the above case,
this would mean, that Base<X> must be defined before I could derive
X from it.


--
Ciao,
Dirk
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]