Topic: pure virtual function question
Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/06 Raw View
In article <3641FD10.9D6E4F5B@prolifics.com>, Hyman Rosen
<hymie@prolifics.com> writes
>> OTOH CodeWarrior Pro4 suports this correctly as well as such things as
>> return void for a function with a void return type.
>
>Not this, I hope, since it's completely incorrect:
>
>class C : public A { };
>A *pA = new B();
>pA->bar(new C());
I said 'correctly', i.e. it supports the use of derived return types in
virtual functions.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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: James Kuyper <kuyper@wizard.net>
Date: 1998/11/06 Raw View
Francis Glassborow wrote:
> In article <3641FD10.9D6E4F5B@prolifics.com>, Hyman Rosen
> <hymie@prolifics.com> writes
> >> OTOH CodeWarrior Pro4 suports this correctly as well as such things as
^^^^
> >> return void for a function with a void return type.
> >Not this, I hope, since it's completely incorrect:
> >class C : public A { };
> >A *pA = new B();
> >pA->bar(new C());
> I said 'correctly', i.e. it supports the use of derived return types in
> virtual functions.
The confusion comes from the fact that the only apparant antecedant for
'this' in your statement was a code fragment which attempted to declare
a virtual B:bar() member with a derived argument type. Your wording gave
the impression that this feature was also acceptable to CodeWarrior.
[ 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: AllanW@my-dejanews.com
Date: 1998/11/06 Raw View
In article <71ufcd$cik$1@news.lth.se>,
Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson) wrote:
> In article <71tnhg$o4v$1@engnews1.eng.sun.com>,
> Steve Clamage <stephen.clamage@sun.com> wrote:
> ...
> >The language rule was relaxed to allow an expression of type
> >void on return statements in void-returning functions, to make
> >templates easier to write. Example:
> >
> > template< class T >
> > T f( T* tp )
> > {
> > // ... compute return_value;
> > return T(return_value);
> > }
> >
> >Under the old rules, you could not instantiate this template
> >on type void. You'd have to write a pointless specialization
> >for type void, increasing the maintenance burden.
> True, but the benefit is not restricted to templates.
> For forwarding funtions the use of 'return void-value' reduces
> the maintenance burden in another way:
> struct Ximpl {void foo();int bar();}
> struct X {
> class Ximpl*impl;
> void foo() {return impl->foo();}
> int bar() {return impl->bar();}
> };
> Allowing 'return void-value' allows uniformity in those functions and
> also ensures that the return-types in X and Ximpl match (which is good
> if you later decide to change the return type of Ximpl::foo() ).
> I complained about the lack of this in 1994 (for forwarding functions),
> and I'm pleased that the standard allows 'return void-value'.
My guess is that this also makes possible an optimization, common
in hand-crafted assembly language but (I suspect) rare in compiled
code from even the best optimizing compilers. It isn't so rare that
a subroutine A calls subroutine B with exactly the same parameters
that were passed to subroutine A, and then, as soon as subroutine B
is finished, returns to subroutine A's caller. When this happens,
the CALL/RETURN sequence can be shortened to a JUMP to subroutine B.
The arguments and A's return value will still be on the stack, and
when B is finished it will return directly to A's caller. This is
a win by almost every measure; it uses less stack space, the return
is slightly faster (perhaps too little to measure), and for paged-
memory systems we avoid an extra reference to the code page with
subroutine A.
Naturally, an optimizing compiler is free to use this technique
whenever applicable. But I suspect it's easier to identify the
special case of
return anotherFunc(same_arg_list_that_I_was_called_with);
than it is to identify the general concept of
anotherFunc(same_arg_list_that_I_was_called_with);
return;
for void functions, and
RvalClass retval = anotherFunc(same_arg_list_that_I_was_called_with);
return retval;
for non-void functions.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: Ron Natalie <ron@sensor.com>
Date: 1998/11/02 Raw View
Jason Thomas wrote:
>
> Can a pure virtual function be implemented to return or receive a
> parameter that is sub-class of the originally declared type? e.g.
No. And it has nothing to do with being pure.
> class c {
> public:
> void doStuff(a* ptr) = 0;
> };
>
> class d:public c {
> public:
> void doStuff(b* ptr) {
> ...
> };
> }
There is no virtual here. but I assume that you just forgot
it when you typed it in (otherwise you'd have bigger problems).
doStuff(b*) doesn't override doStuff(a*), it's a different
function. doStuff(a*) is still undefined in d.
Perhaps you are confusing the feature that llows the return
types to differ (since you can't overload by return type).
It's not clear what you are trying to do anyhow. Presumably
doStuff(A*) provides an interface to something. The function
in d should be declared as taking an A*. This should be
mostly harmless because any B* you try to pass it will
be converted free to A*. If d::doStuff is relatively
certain that the A* it is passed is always a pointer to
type B, it can cast it back.
[ 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: "Irina" <jason@mjmmfg.com>
Date: 1998/11/03 Raw View
Jason Thomas wrote in message <363DD4DC.5C4B@uwaterloo.ca>...
>Can a pure virtual function be implemented to return or receive a
>parameter that is sub-class of the originally declared type? e.g.
No. Here's my thinking.
>class a {
>};
>
>class b:public a {
>};
>
>class c {
>public:
> void doStuff(a* ptr) = 0;
>};
>
>class d:public c {
>public:
> void doStuff(b* ptr) {
> ...
> };
>}
>
>Obviously, b IS_A a so the above code should be valid (at least in my
>opinion). However, I get a "cannot instantiate abstract class c because
>following pure virtual functions are not implemented: void
>doStuff(a*)." If the above code is legal, then maybe my compiler has an
>option to eliminate this error. I'm using Visual C++ 5.0, so if anybody
>knows of this switch/option, could they please let me know. Thanks a
>lot.
There is no bug in VC++ 5 with respect to your code (I use it too).
The function void doStuff(b *ptr); is an overload of the void doStuff(a
*ptr);
because the parameter is a different type, regardless of the fact the b IS_A
a.
The IS_A test is valid only in the sense that b is comprised of an a, and an
"automatic cast" (if you will) is performed if b is used where an a is
required, but they are distinctly different types, thus your function is an
overload.
You must supply a function to satisfy the pure virtual void doStuff(a *);
User code (your's and everyone else's), and call doStuff with a 'b' without
complaint.
However, I sense you need to use member functions and/or data from 'b', not
'a'.
You'll have to perform a cast. Since it's possible you'll create a 'c'
derived from 'a' which could, by accident, be used to call doStuff, you'll
probably want to invoke the dynamic_cast.
---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/03 Raw View
In article <2Ep%1.1179$yE1.3905@server1.news.adelphia.net>, Irina
<jason@mjmmfg.com> writes
>Jason Thomas wrote in message <363DD4DC.5C4B@uwaterloo.ca>...
>>Can a pure virtual function be implemented to return or receive a
>>parameter that is sub-class of the originally declared type? e.g.
>
>No. Here's my thinking.
OTOH you should be able to change the return type to one derived from
the return type of the base class function. This was a specific
relaxation from the ARM that was voted in at least four years ago.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 1998/11/03 Raw View
Jason Thomas wrote:
> Can a pure virtual function be implemented to return or receive a
> parameter that is sub-class of the originally declared type? e.g.
>
> class a {};
> class b:public a {};
> class c { public:void doStuff(a* ptr) = 0; };
> class d:public c { public:void doStuff(b* ptr) {} };
No. To show you why, I'll extend your example:
class e:public a {};
b the_b;
e the_e;
d the_d;
c *c_ptr = &the_d;
c->doStuff(&e);
Notice that we are calling d::doStuff, which expects a b,
through the base class doStuff, which expects only an a.
But we are calling it with an e, which is an a but not a b.
Boom!
[ 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: AllanW@my-dejanews.com
Date: 1998/11/04 Raw View
In article <363DD4DC.5C4B@uwaterloo.ca>,
Jason Thomas <jjthomas@uwaterloo.ca> wrote:
> Can a pure virtual function be implemented to return or receive a
> parameter that is sub-class of the originally declared type? e.g.
>
> class a {
> };
>
> class b:public a {
> };
>
> class c {
> public:
> void doStuff(a* ptr) = 0;
> };
> class d:public c {
> public:
> void doStuff(b* ptr) {
> ...
> };
> }
>
> Obviously, b IS_A a so the above code should be valid (at least in my
> opinion). However, I get a "cannot instantiate abstract class c because
> following pure virtual functions are not implemented: void
> doStuff(a*)."
The code isn't legal. To see why, pretend, for a moment, that it is
legal. Now add this code:
void myfunc(c*cptr, a*aptr)
{
c->doStuff(aptr); /**/
}
int main()
{
d my_c;
a my_a;
myfunc(&my_c, &my_a);
}
Trace through it until you can explain what happens at the line marked
with /**/. What function does it call?
When you get that far, you'll be able to answer the question yourself.
And you'll learn something about C++. It's worth the investment in
time, I promise.
--
AllanW@my-dejanews.com is a "Spam Magnet" -- never read.
Please reply in USENET only, sorry.
-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own
[ 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: rdamon@BeltronicsInspection.com (Richard Damon)
Date: 1998/11/05 Raw View
Jason Thomas <jjthomas@uwaterloo.ca> wrote:
>Can a pure virtual function be implemented to return or receive a
>parameter that is sub-class of the originally declared type? e.g.
return yes
receive no
>class a {
>};
>
>class b:public a {
>};
>
>class c {
>public:
> void doStuff(a* ptr) = 0;
>};
>
>class d:public c {
>public:
> void doStuff(b* ptr) {
> ...
> };
>}
>
>Obviously, b IS_A a so the above code should be valid (at least in my
>opinion).
what should the compiler do with:
d d1;
a a1;
d1.doStuff(&a1);
I suppose they could have let c define a doStuff(b*) and d define a doStuff(a*)
but this is not commonly desired.
If you really only want b pointers to get to d::doStuff you need to define a
d::doStuff(a*) which checks if it was given a b* (possibly via dynamic_cast<b*>)
and then calls a second function d::doStuff(b*). (Having 2 functions will let
the compiler bypass this check if it knows you have a d and a b.
--
richard_damon@iname.com (Redirector to my current best Mailbox)
rdamon@beltronicsInspection.com (Work Adddress)
Richad_Damon@msn.com (Just for Fun)
---
[ 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: "idfix" <idfix@wxs.nl>
Date: 1998/11/05 Raw View
Consider:
class A
{
public:
virtual A *foo();
virtual void bar(A *);
};
class B : public A
{
public:
B *foo(); /* this is allowed, check Stroustrup */
void bar(B *); /* this is not allowed */
};
VC++ rejects the code. The /Za option will make it accept the code, but it
will prevent you from doing anything usefull in your program since it can
not handle the standard header files in that mode. MS did not make a
distinction between <try to be conforming> and <disable MS-specific
extensions> which is too bad.
Silvio Bierman
Jason Thomas wrote in message <363DD4DC.5C4B@uwaterloo.ca>...
>Can a pure virtual function be implemented to return or receive a
>parameter that is sub-class of the originally declared type? e.g.
>
>class a {
>};
>
>class b:public a {
>};
>
>class c {
>public:
> void doStuff(a* ptr) = 0;
>};
>
>class d:public c {
>public:
> void doStuff(b* ptr) {
> ...
> };
>}
>
>Obviously, b IS_A a so the above code should be valid (at least in my
>opinion). However, I get a "cannot instantiate abstract class c because
>following pure virtual functions are not implemented: void
>doStuff(a*)." If the above code is legal, then maybe my compiler has an
>option to eliminate this error. I'm using Visual C++ 5.0, so if anybody
>knows of this switch/option, could they please let me know. Thanks a
>lot.
>---
>[ 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 ]
---
[ 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: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1998/11/05 Raw View
In article <71r075$fa5$1@reader3.wxs.nl>, idfix <idfix@wxs.nl> writes
>class A
>{
>public:
> virtual A *foo();
> virtual void bar(A *);
>};
>class B : public A
>{
>public:
> B *foo(); /* this is allowed, check Stroustrup */
> void bar(B *); /* this is not allowed */
>};
>VC++ rejects the code.
OTOH CodeWarrior Pro4 suports this correctly as well as such things as
return void for a function with a void return type.
Francis Glassborow Chair of Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ 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: Hyman Rosen <hymie@prolifics.com>
Date: 1998/11/05 Raw View
Francis Glassborow wrote:
> In article <71r075$fa5$1@reader3.wxs.nl>, idfix <idfix@wxs.nl> writes
> >class A
> >{
> >public:
> > virtual void bar(A *);
> >};
>
> >class B : public A
> >{
> >public:
> > void bar(B *); /* this is not allowed */
> >};
>
> OTOH CodeWarrior Pro4 suports this correctly as well as such things as
> return void for a function with a void return type.
Not this, I hope, since it's completely incorrect:
class C : public A { };
A *pA = new B();
pA->bar(new C());
[ 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: Biju Thomas <bijuthom@ibm.net>
Date: 1998/11/05 Raw View
Francis Glassborow wrote:
>
> OTOH CodeWarrior Pro4 suports this correctly as well as such things as
> return void for a function with a void return type.
>
You mean something like the following is allowed in the standard?
void foo ()
{
return void;
}
Regards,
Biju Thomas
---
[ 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: stephen.clamage@sun.com (Steve Clamage)
Date: 1998/11/06 Raw View
Biju Thomas <bijuthom@ibm.net> writes:
>Francis Glassborow wrote:
>>
>> OTOH CodeWarrior Pro4 suports this correctly as well as such things as
>> return void for a function with a void return type.
>>
>You mean something like the following is allowed in the standard?
>void foo ()
>{
> return void;
>}
No. The 'return' keyword is followed by an optional expression,
not by a type. But you can write
void foo()
{
return void(0);
}
Not all compilers support this recent language addition. It was
formerly forbidden to put any expression on a return statement
in a void-returning function.
The language rule was relaxed to allow an expression of type
void on return statements in void-returning functions, to make
templates easier to write. Example:
template< class T >
T f( T* tp )
{
// ... compute return_value;
return T(return_value);
}
Under the old rules, you could not instantiate this template
on type void. You'd have to write a pointless specialization
for type void, increasing the maintenance burden.
(This is not really a big deal, but relaxing the rule causes
no problems in the language or the compiler implementation,
and old code which was previously valid is still valid.)
--
Steve Clamage, stephen.clamage@sun.com
[ 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: Email_To::.Hans.Olsson@dna.lth.se (Hans Olsson)
Date: 1998/11/06 Raw View
In article <71tnhg$o4v$1@engnews1.eng.sun.com>,
Steve Clamage <stephen.clamage@sun.com> wrote:
...
>The language rule was relaxed to allow an expression of type
>void on return statements in void-returning functions, to make
>templates easier to write. Example:
>
> template< class T >
> T f( T* tp )
> {
> // ... compute return_value;
> return T(return_value);
> }
>
>Under the old rules, you could not instantiate this template
>on type void. You'd have to write a pointless specialization
>for type void, increasing the maintenance burden.
True, but the benefit is not restricted to templates.
For forwarding funtions the use of 'return void-value' reduces
the maintenance burden in another way:
struct Ximpl {void foo();int bar();}
struct X {
class Ximpl*impl;
void foo() {return impl->foo();}
int bar() {return impl->bar();}
};
Allowing 'return void-value' allows uniformity in those functions and
also ensures that the return-types in X and Ximpl match (which is good
if you later decide to change the return type of Ximpl::foo() ).
I complained about the lack of this in 1994 (for forwarding functions),
and I'm pleased that the standard allows 'return void-value'.
--
// Home page http://www.dna.lth.se/home/Hans_Olsson/
// Email To..Hans.Olsson@dna.lth.se [Please no junk e-mail]
---
[ 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: Jason Thomas <jjthomas@uwaterloo.ca>
Date: 1998/11/02 Raw View
Can a pure virtual function be implemented to return or receive a
parameter that is sub-class of the originally declared type? e.g.
class a {
};
class b:public a {
};
class c {
public:
void doStuff(a* ptr) = 0;
};
class d:public c {
public:
void doStuff(b* ptr) {
...
};
}
Obviously, b IS_A a so the above code should be valid (at least in my
opinion). However, I get a "cannot instantiate abstract class c because
following pure virtual functions are not implemented: void
doStuff(a*)." If the above code is legal, then maybe my compiler has an
option to eliminate this error. I'm using Visual C++ 5.0, so if anybody
knows of this switch/option, could they please let me know. Thanks a
lot.
---
[ 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 ]