 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Roger Guest
|
Posted: Tue Aug 29, 2006 3:06 am Post subject: Calling virtual method of base class nested in template clas |
|
|
Hi all.
Here's a little quandry I've run in to and can't tell if it's a compiler
bug, or if it's bad code. First, here's the code:
===================================
#include <stdio.h>
template < typename T >
class B
{
public:
B( ) { }
class N1
{
public:
N1( ) { };
class N2
{
public:
N2( ) { };
virtual void f( )
{
printf( " B< >::N1::N2::f( )\n" );
}
};
};
T _m;
};
class D : public B< int >
{
public:
class N1 : public B< int >::N1
{
public:
N1( ) : B< int >::N1( ) { };
class N2 : public B< int >::N1::N2
{
public:
N2( ) : B< int >::N1::N2( ) { };
virtual void f( )
{
printf( " D::N1::N2::f( )\n" );
( ( B< int >::N1::N2* ) this )->f( );
}
};
};
};
void
main( int argc, char* argv[ ] )
{
D::N1::N2 n2;
n2.f( );
}
==================================
Invoking n2.f( ) causes an infinite loop, dumping out "D::N1::N2::f( )"
ad-nausium. I am trying to call the base-class f( ) in B::N1::N2, but the
compiler just generates code that instead calls D::N1::N2::f( ) recursively.
What am I doning wrong? How can I call the base's f( )?
Thanks for any help you can offer!
- Roger
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Jens Theisen Guest
|
Posted: Tue Aug 29, 2006 4:05 am Post subject: Re: Calling virtual method of base class nested in template |
|
|
Roger wrote:
| Quote: | What am I doning wrong? How can I call the base's f( )?
|
This way:
virtual void f( )
{
printf( " D::N1::N2::f( )\n" );
B< int >::N1::N2::f( );
}
:)
Jens
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
Roger Guest
|
Posted: Tue Aug 29, 2006 8:26 pm Post subject: Re: Calling virtual method of base class nested in template |
|
|
{ please watch your quoting. did you actually need to quote? -mod }
Actually, I came up with a simpler example that exhibits the same bug (no
template, and nesting at only a single level):
#include <iostream>
class B
{
public:
B( ) { }
class N1
{
public:
N1( ) { };
virtual void f( )
{
std::cout << "B< >::N1::f( )" << std::endl;
}
};
};
class D : public B
{
public:
class N1 : public B::N1
{
public:
N1( ) : B::N1( ) { };
virtual void f( )
{
typedef B::N1 BN1;
std::cout << "D::N1::f( )" << std::endl;
BN1::f( );
}
};
};
void
main( int argc, char* argv[ ] )
{
D::N1 n1;
n1.f( );
}
However, the problem is worked around by changing the name of D::N1 to
something other than N1. Apperently, the VC6.0 compiler becomes confused as
to which N1 I was referring and just assumed the most derived N1, rather
than the one specified by the typedef (i.e., the N1 in B).
When I renamed N1 to, say, Joe, it worked.
Thanks,
- Roger
"Jens Theisen" <jth02 (AT) arcor (DOT) de> wrote in message
news:44f36da0$0$20038$9b4e6d93 (AT) newsspool4 (DOT) arcor-online.net...
| Quote: | Roger wrote:
What am I doning wrong? How can I call the base's f( )?
This way:
virtual void f( )
{
printf( " D::N1::N2::f( )\n" );
B< int >::N1::N2::f( );
}
:)
Jens
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
kanze Guest
|
Posted: Tue Aug 29, 2006 11:52 pm Post subject: Re: Calling virtual method of base class nested in template |
|
|
Roger wrote:
| Quote: | Here's a little quandry I've run in to and can't tell if it's
a compiler bug, or if it's bad code. First, here's the code:
|
Which you really could have considerably simplified. The
problem has nothing to do with nested classes.
| Quote: | ===================================
#include <stdio.h
template < typename T
class B
{
public:
B( ) { }
class N1
{
public:
N1( ) { };
class N2
{
public:
N2( ) { };
virtual void f( )
{
printf( " B< >::N1::N2::f( )\n" );
}
};
};
T _m;
};
class D : public B< int
{
public:
class N1 : public B< int >::N1
{
public:
N1( ) : B< int >::N1( ) { };
class N2 : public B< int >::N1::N2
{
public:
N2( ) : B< int >::N1::N2( ) { };
virtual void f( )
{
printf( " D::N1::N2::f( )\n" );
( ( B< int >::N1::N2* ) this )->f( );
|
Which invokes the virtual function mechanism (and probably
results in a endless recursion).
How should this be any different from:
B< int >::N1::N2* p ;
p->f() ;
invoked on any object, anywhere.
If you want to invoke the base class function, you have to say
so:
p->B< int >::N1::N2::f() ;
(or in this case, the same thing, without the p->).
You mean 'int', of course. void is not a legal return value for
main.
| Quote: | main( int argc, char* argv[ ] )
{
D::N1::N2 n2;
n2.f( );
}
==================================
Invoking n2.f( ) causes an infinite loop, dumping out
"D::N1::N2::f( )" ad-nausium.
|
It's not looping, it's recursing. And it's only conceptually
infinite: you'll run out of stack sooner or later, and then it
will probably stop.
| Quote: | I am trying to call the base-class f( ) in B::N1::N2, but the
compiler just generates code that instead calls D::N1::N2::f()
recursively.
|
Typical case of the compiler doing what you said, and not what
you wanted.
| Quote: | What am I doning wrong? How can I call the base's f()?
|
By using a qualified name for the function.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ] |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|