
March 15th, 2006, 08:15 PM
| | | Re: Simultaneously overriding multiple member functions
Mark P wrote:[color=blue]
> #include <iostream>
> using namespace std;
>
> struct Base
> {
> virtual int foo () {return 1;}
> virtual int foo (int i) {return 2;}
>
> virtual ~Base () {}
> };
>
> struct Derived : Base
> {
> virtual int foo (int i = 3) {return i;}[/color]
This overrides Base::foo(int) and also defines a default argument for
it. The default argument will be in effect only if you call the method
from a reference to Derived.
It also hides Base::foo(). It does NOT override it. Base::foo(), being
hidden, cannot be called from a Derived object, unless you explicitelly
qualify the call.
[color=blue]
> };
>
> int main ()
> {
> Derived* d1 = new Derived;
> Base* d2 = new Derived;
> cout << d1->foo() << " " << d1->foo(4) << endl;[/color]
You are calling throu a Derived. The only visible member is
Derived::foo(int). It has a default argument. Both calls are to that
method, the first one will use the default.
[color=blue]
> cout << d2->foo() << " " << d2->foo(4) << endl;[/color]
You are calling throu a Base (with dynamic type Derived). Both methods
are visible. The default value of Derived::foo(int) is not in effect.
Base::foo() is not overridden. Base::foo(int) is overridden.
The first call is to Base::foo(), which is not overridden.
The only visible member is Derived::foo(int). It has a default argument.
Both calls are to that method, the first one will use the default.
[color=blue]
> I was a little bit surprised to see the output of this short program:
>
> 3 4
> 1 4[/color]
We aren't ;-)
[color=blue]
>
> Specifically, the '1' was unexpected. What rule (or rules) make it so
> that d2->foo() calls Base::foo() rather than Derived::foo() with a
> default argument?[/color]
See above.
Also consider (note: I'm writing straight in the news client, forgive
any typing error):
/** ****** **/
struct Base {
virtual void foo();
virtual void foo(int);
};
struct Derived {
virtual foo();
};
.....
Derived d;
d.foo(2); // ERROR
the Base::foo(int) is hidden. If you want to call it you need:
d.Base::foo(2);
/** ****** **/
struct Base {
virtual void foo(int);
};
struct Derived {
virtual foo(int i=5);
};
.....
Base *p=new Derived;
p->foo(); // ERROR
the default is in effect for a call through Derived, but we are calling
through Base. And this is somewhat obvious: what would it be if you also
had:
struct Descendant: public Derived {
virtual foo(int i=7);
}; | 
March 15th, 2006, 09:15 PM
| | | Re: Simultaneously overriding multiple member functions
AnalogFile wrote:
Sorry. Some cut&paste mixup.
The previous post is incorrect. This part:
[color=blue][color=green]
>> cout << d2->foo() << " " << d2->foo(4) << endl;[/color]
>
> You are calling throu a Base (with dynamic type Derived). Both methods
> are visible. The default value of Derived::foo(int) is not in effect.
> Base::foo() is not overridden. Base::foo(int) is overridden.
>
> The first call is to Base::foo(), which is not overridden.
>
> The only visible member is Derived::foo(int). It has a default argument.
> Both calls are to that method, the first one will use the default.
>[/color]
Should have been:
[color=blue]
> cout << d2->foo() << " " << d2->foo(4) << endl;[/color]
You are calling through a Base (with dynamic type Derived). Both methods
are visible. The default value of Derived::foo(int) is not in effect.
Base::foo() is not overridden. Base::foo(int) is overridden.
The first call is to Base::foo(), which is not overridden and is
therefore executed.
The second call is to Base::foo(int) which is overridden by
Derived::foo(int), the latter is therefore executed. | 
March 15th, 2006, 10:55 PM
| | | Re: Simultaneously overriding multiple member functions
AnalogFile wrote:[color=blue]
> Mark P wrote:[color=green]
>> #include <iostream>
>> using namespace std;
>>
>> struct Base
>> {
>> virtual int foo () {return 1;}
>> virtual int foo (int i) {return 2;}
>>
>> virtual ~Base () {}
>> };
>>
>> struct Derived : Base
>> {
>> virtual int foo (int i = 3) {return i;}[/color]
>
> This overrides Base::foo(int) and also defines a default argument for
> it. The default argument will be in effect only if you call the method
> from a reference to Derived.
> It also hides Base::foo(). It does NOT override it. Base::foo(), being
> hidden, cannot be called from a Derived object, unless you explicitelly
> qualify the call.
>[color=green]
>> };
>>
>> int main ()
>> {
>> Derived* d1 = new Derived;
>> Base* d2 = new Derived;
>> cout << d1->foo() << " " << d1->foo(4) << endl;[/color]
>
> You are calling throu a Derived. The only visible member is
> Derived::foo(int). It has a default argument. Both calls are to that
> method, the first one will use the default.
>[color=green]
>> cout << d2->foo() << " " << d2->foo(4) << endl;[/color]
>
> You are calling throu a Base (with dynamic type Derived). Both methods
> are visible. The default value of Derived::foo(int) is not in effect.
> Base::foo() is not overridden. Base::foo(int) is overridden.
>
> The first call is to Base::foo(), which is not overridden.
>
> The only visible member is Derived::foo(int). It has a default argument.
> Both calls are to that method, the first one will use the default.
>[color=green]
>> I was a little bit surprised to see the output of this short program:
>>
>> 3 4
>> 1 4[/color]
>
> We aren't ;-)
>[color=green]
>>
>> Specifically, the '1' was unexpected. What rule (or rules) make it so
>> that d2->foo() calls Base::foo() rather than Derived::foo() with a
>> default argument?[/color]
>
> See above.
> Also consider (note: I'm writing straight in the news client, forgive
> any typing error):
>
> /** ****** **/
>
> struct Base {
> virtual void foo();
> virtual void foo(int);
> };
> struct Derived {
> virtual foo();
> };
> ....
> Derived d;
> d.foo(2); // ERROR
>
>
> the Base::foo(int) is hidden. If you want to call it you need:
>
> d.Base::foo(2);
>
>
>
> /** ****** **/
>
> struct Base {
> virtual void foo(int);
> };
> struct Derived {
> virtual foo(int i=5);
> };
> ....
> Base *p=new Derived;
> p->foo(); // ERROR
>
> the default is in effect for a call through Derived, but we are calling
> through Base. And this is somewhat obvious: what would it be if you also
> had:
>
> struct Descendant: public Derived {
> virtual foo(int i=7);
> };[/color]
Very clear and helpful! Thanks a lot.
Mark | | Thread Tools | Search this Thread | | | |
Posting Rules
| You may not post new threads You may not post replies You may not post attachments You may not edit your posts HTML code is Off | | | | | | What is Bytes?
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 205,338 network members.
|