473,503 Members | 10,012 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Calling a virtual method in a specific class

Hi folks,

I have a small hierarchy with a virtual method which is overridden in
the most derived class. I also have a method that needs to call two
versions of this.. the most derived and the base class:

#include <iostream>

struct A
{
virtual void Foo() { std::cout << "A::MyFunc" << std::endl; }
};

template< class AType >
struct B : public AType
{
void Bar() { Foo(); AType::Foo(); }
};

struct C : public B< A >
{
virtual void Foo() { std::cout << "C::MyFunc" << std::endl; }
};

int main()
{
B< A >* b = new C;
b->Bar();
delete b;
}

This works fine on gcc-3.3.3. I just read in the changes for the new
version of gcc (http://gcc.gnu.org/gcc-3.4/changes.html) that this is no
longer acceptable (and is unacceptable in standard C++).

Specifically -- "In a template definition, unqualified names will no
longer find members of a dependent base". So B::Bar would have to change to:

void Bar() { this->Foo(); this->AType::Foo(); }

My question is, is this legal C++? I'm hoping it will produce the output:

C::MyFunc
A::MyFunc

And it does on my current compiler, but is it standard C++?

Thanks,
-- Pete
Jul 22 '05 #1
8 1204
* Pete Vidler <pv*****@mailblocks.com> schriebt:

I have a small hierarchy with a virtual method which is overridden in
the most derived class. I also have a method that needs to call two
versions of this.. the most derived and the base class:

#include <iostream>

struct A
{
virtual void Foo() { std::cout << "A::MyFunc" << std::endl; }
};

template< class AType >
struct B : public AType
{
void Bar() { Foo(); AType::Foo(); }
};

struct C : public B< A >
{
virtual void Foo() { std::cout << "C::MyFunc" << std::endl; }
};

int main()
{
B< A >* b = new C;
b->Bar();
delete b;
}

This works fine on gcc-3.3.3. I just read in the changes for the new
version of gcc (http://gcc.gnu.org/gcc-3.4/changes.html) that this is no
longer acceptable (and is unacceptable in standard C++).

Specifically -- "In a template definition, unqualified names will no
longer find members of a dependent base". So B::Bar would have to change to:

void Bar() { this->Foo(); this->AType::Foo(); }

My question is, is this legal C++? I'm hoping it will produce the output:

C::MyFunc
A::MyFunc

And it does on my current compiler, but is it standard C++?


Yes. This was discussed here very recently. I suggested a 'using'
declaration, but didn't know why or how it worked; someone else (sorry,
don't remember who) then explained the whole thing -- namely dependent
name lookup -- and summarized three techniques: 'using' directive,
'this->' qualification, and 'ClassName::' qualification.

Classname qualification is of course no good for virtual calls.

And 'this->' qualification is not very practical.

So I suggest placing a few 'using'-directives here & there; in your
example
template< class AType >
struct B : public AType
{
using AType::Foo; // For the unqualified (virtual) call.
void Bar() { Foo(); AType::Foo(); }
};
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2
* Pete Vidler <pv*****@mailblocks.com> schriebt:

I have a small hierarchy with a virtual method which is overridden in
the most derived class. I also have a method that needs to call two
versions of this.. the most derived and the base class:

#include <iostream>

struct A
{
virtual void Foo() { std::cout << "A::MyFunc" << std::endl; }
};

template< class AType >
struct B : public AType
{
void Bar() { Foo(); AType::Foo(); }
};

struct C : public B< A >
{
virtual void Foo() { std::cout << "C::MyFunc" << std::endl; }
};

int main()
{
B< A >* b = new C;
b->Bar();
delete b;
}

This works fine on gcc-3.3.3. I just read in the changes for the new
version of gcc (http://gcc.gnu.org/gcc-3.4/changes.html) that this is no
longer acceptable (and is unacceptable in standard C++).

Specifically -- "In a template definition, unqualified names will no
longer find members of a dependent base". So B::Bar would have to change to:

void Bar() { this->Foo(); this->AType::Foo(); }

My question is, is this legal C++? I'm hoping it will produce the output:

C::MyFunc
A::MyFunc

And it does on my current compiler, but is it standard C++?


Yes. This was discussed here very recently. I suggested a 'using'
declaration, but didn't know why or how it worked; someone else (sorry,
don't remember who) then explained the whole thing -- namely dependent
name lookup -- and summarized three techniques: 'using' directive,
'this->' qualification, and 'ClassName::' qualification.

Classname qualification is of course no good for virtual calls.

And 'this->' qualification is not very practical.

So I suggest placing a few 'using'-directives here & there; in your
example
template< class AType >
struct B : public AType
{
using AType::Foo; // For the unqualified (virtual) call.
void Bar() { Foo(); AType::Foo(); }
};
--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #3
* Pete Vidler <pv*****@mailblocks.com> schriebt:

void Bar() { this->Foo(); this->AType::Foo(); }


Sorry, didn't see that first time around.

The second 'this->' qualification is entirely superflous (since the
class qualification already tells the compiler Foo is a dependent name)
and so it can and should be omitted.

I'd also omit the first 'this->' and use a 'using' statement instead.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #4
* Pete Vidler <pv*****@mailblocks.com> schriebt:

void Bar() { this->Foo(); this->AType::Foo(); }


Sorry, didn't see that first time around.

The second 'this->' qualification is entirely superflous (since the
class qualification already tells the compiler Foo is a dependent name)
and so it can and should be omitted.

I'd also omit the first 'this->' and use a 'using' statement instead.

--
A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #5
Alf P. Steinbach wrote in news:40****************@news.individual.net:
* Pete Vidler <pv*****@mailblocks.com> schriebt:

[snip]

Yes. This was discussed here very recently. I suggested a 'using'
declaration, but didn't know why or how it worked; someone else
(sorry, don't remember who) then explained the whole thing -- namely
dependent name lookup -- and summarized three techniques: 'using'
directive, 'this->' qualification, and 'ClassName::' qualification.

Classname qualification is of course no good for virtual calls.

And 'this->' qualification is not very practical.

So I suggest placing a few 'using'-directives here & there; in your
example
template< class AType >
struct B : public AType
{
using AType::Foo; // For the unqualified (virtual) call.
void Bar() { Foo(); AType::Foo(); }
};


As much as I like the using alternative its also important to
note that it has other effects (often desirable):

- Un-hiding AType::Foo in the case where B also declares a Foo()
member.

- Access control, if AType::Foo is protected the above using
would also make AType::Foo() a public member of B.
As a side note I was inspired to try this:

#include <iostream>
#include <ostream>

struct X
{
protected:

typedef int type;
};

template <typename T > struct Y : T
{
using typename T::type;
type get() { return 1; }
};

int main()
{
using namespace std;

Y< X >::type i = 3;
Y< X > yx;

cerr << i << ", " << yx.get() << '\n';
}

MS VC 7.1 and CBuilderX (prerelease) both accepted the code, gcc 3.2.3
(MingW) objected to the 'using typename ...' and gcc 3.4 (prerelease)
was ok until I added the get() member function.

Oh well back too typedef typename ...

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #6
Alf P. Steinbach wrote in news:40****************@news.individual.net:
* Pete Vidler <pv*****@mailblocks.com> schriebt:

[snip]

Yes. This was discussed here very recently. I suggested a 'using'
declaration, but didn't know why or how it worked; someone else
(sorry, don't remember who) then explained the whole thing -- namely
dependent name lookup -- and summarized three techniques: 'using'
directive, 'this->' qualification, and 'ClassName::' qualification.

Classname qualification is of course no good for virtual calls.

And 'this->' qualification is not very practical.

So I suggest placing a few 'using'-directives here & there; in your
example
template< class AType >
struct B : public AType
{
using AType::Foo; // For the unqualified (virtual) call.
void Bar() { Foo(); AType::Foo(); }
};


As much as I like the using alternative its also important to
note that it has other effects (often desirable):

- Un-hiding AType::Foo in the case where B also declares a Foo()
member.

- Access control, if AType::Foo is protected the above using
would also make AType::Foo() a public member of B.
As a side note I was inspired to try this:

#include <iostream>
#include <ostream>

struct X
{
protected:

typedef int type;
};

template <typename T > struct Y : T
{
using typename T::type;
type get() { return 1; }
};

int main()
{
using namespace std;

Y< X >::type i = 3;
Y< X > yx;

cerr << i << ", " << yx.get() << '\n';
}

MS VC 7.1 and CBuilderX (prerelease) both accepted the code, gcc 3.2.3
(MingW) objected to the 'using typename ...' and gcc 3.4 (prerelease)
was ok until I added the get() member function.

Oh well back too typedef typename ...

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #7
Alf P. Steinbach wrote:
* Pete Vidler <pv*****@mailblocks.com> schriebt:
void Bar() { this->Foo(); this->AType::Foo(); }


Sorry, didn't see that first time around.

The second 'this->' qualification is entirely superflous (since the
class qualification already tells the compiler Foo is a dependent name)
and so it can and should be omitted.

I'd also omit the first 'this->' and use a 'using' statement instead.


Okay, thanks.

-- Pete
Jul 22 '05 #8
Alf P. Steinbach wrote:
* Pete Vidler <pv*****@mailblocks.com> schriebt:
void Bar() { this->Foo(); this->AType::Foo(); }


Sorry, didn't see that first time around.

The second 'this->' qualification is entirely superflous (since the
class qualification already tells the compiler Foo is a dependent name)
and so it can and should be omitted.

I'd also omit the first 'this->' and use a 'using' statement instead.


Okay, thanks.

-- Pete
Jul 22 '05 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
1738
by: Raymond Lewallen | last post by:
I read this on this website page http://www.vbip.com/books/1861004915/chapter_4915_06.asp: Unlike many object-oriented languages, all methods in VB.NET are virtual. Now in BOL, Under...
8
1204
by: Pete Vidler | last post by:
Hi folks, I have a small hierarchy with a virtual method which is overridden in the most derived class. I also have a method that needs to call two versions of this.. the most derived and the...
2
2495
by: Edward Diener | last post by:
In C++ an overridden virtual function in a derived class must have the exact same signature of the function which is overridden in the base class, except for the return type which may return a...
1
1583
by: Bern McCarty | last post by:
What do you make of this? I cannot tell for sure but it almost seems as the the transition thunk to get back from the native bool method to the managed caller is looking at eax and, if any bit is...
11
3395
by: ypjofficial | last post by:
Hello All, So far I have been reading that in case of a polymorphic class ( having at least one virtual function in it), the virtual function call get resolved at run time and during that the...
8
2003
by: Mike C# | last post by:
Suppose I have a base class "foo". Another class, "bar" derives from it. Base class "foo" has a method called "rob_the_liquor_store()", and the inherited class "bar" overrides this method with one...
6
5626
by: Henrik Goldman | last post by:
Hi I've had a problem with gcc mac osx which I think I figured out. I would like to double check with people here to see if my understanding is correct: I have a class A which class B inherit...
3
4683
by: Klaus | last post by:
Hi, I have an existing VC 6 MFC application which communicates asynchronly with a VC 2005 managed code dll. I use an unmanaged base class with virtual functions to access methods in the MFC...
7
1992
by: =?ISO-8859-1?Q?Fernando_G=F3mez?= | last post by:
Hello all. I have this class with a virtual method and a constructor that calls this virtual method. A derived class overrides this virtual method, so I expected that when the base's constructor is...
0
7194
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7070
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7267
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7316
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7449
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5566
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
4666
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
3148
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
729
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.