Topic: Access to protected members of an instance of your base class.


Author: Salters <salters@lucent.com>
Date: 1999/09/13
Raw View
Siemel B. Naran wrote:

> On 10 Sep 1999 15:48:41 GMT, Salters <salters@lucent.com> wrote:

> >My problem is that I am writing a streambuf class that is
> >implemented as a wrapper around another streambuf. To
> >put it into a stream, I get the old streambuf, and use
> >that to construct my class. I keep a pointer to the old
> >streambuf in my class, and install the new streambuf.

> Can you derive your class myspace::streambuf from std::streambuf?
> Use private inheritance if you don't want general clients to see
> the isA relationship.

The point is, my streambuf is-A streambuf. It will be used to replace
another streambuf, so it better be. This is precisely where you
need public derivation.

> >class MyStreamBuf : public std::streambuf {
> >       streambuf* orig;
> >       virtual int_type underflow {
> >               return static_cast<MyStreamBuf*>(orig)->underflow();
> >               }
> >};

> Why do you derive from std::streambuf and also hold a std::streambuf *.

Because my base class is nothing more than a streambuf (which is for
all practical purposes an ABC), while the streambuf* is a pointer
to any of the derived types of streambuf* - in theory, it could be
a pointer to another instance of my streambuf. The idea is that this
streambuf is a filter: its input interface must match the interface
used on its output, and that's streambuf.

The problem I still have is: how I can use the interface of the output
streambuf ("orig")?
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Stephan Keil <Stephan.Keil@gmx.de>
Date: 1999/09/11
Raw View
> >Is it always safe to use static_cast in this way (i.e. casting to a
> >derived class and call a virtual function although the object is not a
> >derived)??

> IMHO, it is safe. Because you are only cheating a compiler to believe that
> the object is of the derived type and thus allowing this call, while the
> virtual function call is still based on the dynamic type of the object that
> doesn't change.

What does the standard say?


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Salters <salters@lucent.com>
Date: 1999/09/10
Raw View
Bit complicated title, eh?

My problem is that I am writing a streambuf class that is
implemented as a wrapper around another streambuf. To
put it into a stream, I get the old streambuf, and use
that to construct my class. I keep a pointer to the old
streambuf in my class, and install the new streambuf.

My understanding is that I have to forward the virtual
underflow functions. The base class streambuf will call
these to get a number of new characters at a time. My
class would then call the underflow functions of the
old streambuf, and get a first peek at them.
Unfortunately, I cannot directly call the underflow
functions of the old streambuf -they are protected.
My streambuf is derived from std::streambuf, in which
they were declared. But I want to call these functions
on a pointer I hold, not my base class.

My current hack is somewhat dubious: I cast the streambuf
pointer I hold into a pointer of my own class (using
static_cast<>, of course) and then call the underflow
functions. This works, but I have a distinct feeling I'm
cheating.

The basic idea of the code:

class MyStreamBuf : public std::streambuf {
 streambuf* orig;
 virtual int_type underflow {
  return static_cast<MyStreamBuf*>(orig)->underflow();
  }
};

Any other way I could implement a streambuf in terms of another
streambuf?

Michiel Salters


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Stephan Keil <Stephan.Keil@gmx.de>
Date: 1999/09/10
Raw View
> class MyStreamBuf : public std::streambuf {
>         streambuf* orig;
>         virtual int_type underflow {
>                 return static_cast<MyStreamBuf*>(orig)->underflow();
>                 }
> };
>
Is it always safe to use static_cast in this way (i.e. casting to a
derived class and call a virtual function although the object is not a
derived)??

> Any other way I could implement a streambuf in terms of another
> streambuf?

What about:

 template<class StrBuf>
 class MyStrBuf : public StrBuf
 {
   virtual int_type underflow()
     {
       //...
     }
   //...
 };

 int main()
 {
   MyStrBuf<BaseStrBuf> mystr;
   //...
 }

Now you are deriving from the strbuf you are extending. Unfortunately you
cannot call a special constructor for the streambuf you are extending
(which is IMHO an unsolved problem in C++; any comments on that?).


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/11
Raw View
On 10 Sep 1999 20:32:31 GMT, Stephan Keil <Stephan.Keil@gmx.de> wrote:

>> class MyStreamBuf : public std::streambuf {
>>         streambuf* orig;
>>         virtual int_type underflow {
>>                 return static_cast<MyStreamBuf*>(orig)->underflow();
>>                 }
>> };
>>
>Is it always safe to use static_cast in this way (i.e. casting to a
>derived class and call a virtual function although the object is not a
>derived)??

It is safe to static_cast from Base* to Derived3* if you know for sure
that the Base& object in question really is a Derived3*.  If you are
wrong, then the behaviour of the program is undefined.

We often use this kind of static_cast in recursive derivation.

template <class What>
class Action
{
   public:
      int action() const
      {
         const What& me=static_cast<const What&>(me);
         return me.variable();
      }
};

class Silly : public Action<Silly> { ... };

--
--------------
siemel b naran
--------------
---
[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Gene Bushuyev" <gbush@my-deja.com>
Date: 1999/09/11
Raw View
Stephan Keil wrote in message <37D95C65.EF335BC0@gmx.de>...
>
>> class MyStreamBuf : public std::streambuf {
>>         streambuf* orig;
>>         virtual int_type underflow {
>>                 return static_cast<MyStreamBuf*>(orig)->underflow();
>>                 }
>> };
>>
>Is it always safe to use static_cast in this way (i.e. casting to a
>derived class and call a virtual function although the object is not a
>derived)??


IMHO, it is safe. Because you are only cheating a compiler to believe that
the object is of the derived type and thus allowing this call, while the
virtual function call is still based on the dynamic type of the object that
doesn't change.

Gene Bushuyev




[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/11
Raw View
On 10 Sep 1999 15:48:41 GMT, Salters <salters@lucent.com> wrote:

>My problem is that I am writing a streambuf class that is
>implemented as a wrapper around another streambuf. To
>put it into a stream, I get the old streambuf, and use
>that to construct my class. I keep a pointer to the old
>streambuf in my class, and install the new streambuf.

Can you derive your class myspace::streambuf from std::streambuf?
Use private inheritance if you don't want general clients to see
the isA relationship.

The most extreme case is to make your class myspace::streambuf
not derive from std::streambuf, but make a private nested class
myspace::streambuf::streambuf derived from std::streambuf.
Then class myspace::streambuf has a pointer to a
myspace::streambuf::streambuf.


>class MyStreamBuf : public std::streambuf {
> streambuf* orig;
> virtual int_type underflow {
>  return static_cast<MyStreamBuf*>(orig)->underflow();
>  }
>};

Why do you derive from std::streambuf and also hold a std::streambuf *.


--
--------------
siemel b naran
--------------


[ 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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]