virtual functions in inherited class

V

vabby

Hi
I have run into an eerie situation whihc i cant make out. I have a
class A which has has two virtual functions with the same name, having
diff arguments. Basically a case of function overloading.

Also there is a class B, which is derived form A and has one of the
functions in the base class overridden.

So this is the scenario.

Class A
{
public:
int virtual test(int a, int b)
{
cout<<"inside A::test(int,int)";
return a+b;
}

float virtual test(float a, float b)
{
cout<<"inside A::test(float,float)";
return a+b;

}
}

Class B : public A
{
public:
int test(int a, int b)
{
cout<<"inside B::test(int,int)";
return a + b;
}
}

Now i have the following code in the main function
B* obj = new B();
obj->test(2,3); //this wrks fine
obj->test(2.3,2.5); //this is giving me compilation error.
// I dont known why ???

the second call fails during compilation. Ideally it should make a call
to A::test(float, float)

Plz let me know if i m doing anything wrong

Tx
Vaibhav
 
O

Ondra Holub

vabby napsal:
Hi
I have run into an eerie situation whihc i cant make out. I have a
class A which has has two virtual functions with the same name, having
diff arguments. Basically a case of function overloading.

Also there is a class B, which is derived form A and has one of the
functions in the base class overridden.

So this is the scenario.

Class A
{
public:
int virtual test(int a, int b)
{
cout<<"inside A::test(int,int)";
return a+b;
}

float virtual test(float a, float b)
{
cout<<"inside A::test(float,float)";
return a+b;

}
}

Class B : public A
{
public:
int test(int a, int b)
{
cout<<"inside B::test(int,int)";
return a + b;
}
}

Now i have the following code in the main function
B* obj = new B();
obj->test(2,3); //this wrks fine
obj->test(2.3,2.5); //this is giving me compilation error.
// I dont known why ???

2.3 is double, not float. Compiler does not know, whether to convert it
to int or float. Try

obj->test(2.3f, 2.5f);
 
V

Victor Bazarov

vabby said:
Hi
I have run into an eerie situation whihc i cant make out. I have a
class A which has has two virtual functions with the same name, having
diff arguments. Basically a case of function overloading.

Also there is a class B, which is derived form A and has one of the
functions in the base class overridden.

....and the other one _hidden_. Learn about name hiding, read the FAQ
about it.
So this is the scenario.

Class A

C++ is case sensitive. You posted code does not compile. Please next
time do not type your code directly into your posting and instead copy
and paste it from your text editor. Read FAQ 5.8.
{
public:
int virtual test(int a, int b)
{
cout<<"inside A::test(int,int)";
return a+b;
}

float virtual test(float a, float b)
{
cout<<"inside A::test(float,float)";
return a+b;

}
}

Class B : public A
{
public:
int test(int a, int b)
{
cout<<"inside B::test(int,int)";
return a + b;
}
}

Now i have the following code in the main function
B* obj = new B();
obj->test(2,3); //this wrks fine
obj->test(2.3,2.5); //this is giving me compilation error.
// I dont known why ???

Because 'test(float,float)' does not exist in 'B' scope. You need
to bring it in with a "using" declaration. See FAQ.
the second call fails during compilation. Ideally it should make a
call to A::test(float, float)

Plz let me know if i m doing anything wrong

Your understanding of name lookup is incomplete, perhaps.

V
 
V

vabby

Actuall I just used floats and ints to illustrate the case. I am using
my own classes, instead of ints and floats.

Hence the declarations are as follows:

virtual class1 A::test(class1, class1);

virtual class2 A::test(class2, class2);

virtual class2 B::test(class2, class2);
 
S

Salt_Peter

vabby said:
Hi
I have run into an eerie situation whihc i cant make out. I have a
class A which has has two virtual functions with the same name, having
diff arguments. Basically a case of function overloading.

Also there is a class B, which is derived form A and has one of the
functions in the base class overridden.

So this is the scenario.

Class A
{
public:
int virtual test(int a, int b)
{
cout<<"inside A::test(int,int)";
return a+b;
}

float virtual test(float a, float b)
{
cout<<"inside A::test(float,float)";
return a+b;

}
}
;

class, not Class
Class B : public A
{
public:
int test(int a, int b)
{
cout<<"inside B::test(int,int)";
return a + b;
}
}

Now i have the following code in the main function
B* obj = new B();
obj->test(2,3); //this wrks fine
obj->test(2.3,2.5); //this is giving me compilation error.
// I dont known why ???

the second call fails during compilation. Ideally it should make a call
to A::test(float, float)

Plz let me know if i m doing anything wrong

Nothing is wrong. Change the name of test(int,int) to something else
than test and the function will no longer be hidden by the same name in
class B. The same happens if you only had a non-virtual function
test(int, float, float) in class B.

Change test(float, float) to test(char,char) and modify class B to:

class B : public A
{
public:
int test(int a, int b)
{
std::cout<<"inside B::test(int,int)\n";
return a + b;

}
using A::test; // !!!
};

int main()
{
B b;
b.test(0 , 1);
b.test('a', 'b'); // and it works
}
 
C

Chris Theis

Ondra Holub said:
vabby napsal:

2.3 is double, not float. Compiler does not know, whether to convert it
to int or float. Try

obj->test(2.3f, 2.5f);

Sorry, but where did you get this idea from? The reason that for the problem
is that name hiding occurs and like Victor or others pointed out a using
statement needs to be added to bring test(float, float) into the context of
B.
Regarding the conversion there is a clear order of conversions defined by
the standard. Naturally, before a "change of type" - in this case I mean
from floating point to integer - will be considered, the compiler will try
to find a floating point conversion. It is actually capable of doing this
even if the types are of a different size like double and float. In the case
that the value can be represented by the new type no change occurs,
otherwise rounding and a loss of precision will take place and the compiler
might give you a warning.


Cheers
Chris
 
O

Ondra Holub

Chris Theis napsal:
Sorry, but where did you get this idea from? The reason that for the problem
is that name hiding occurs and like Victor or others pointed out a using
statement needs to be added to bring test(float, float) into the context of
B.
Regarding the conversion there is a clear order of conversions defined by
the standard. Naturally, before a "change of type" - in this case I mean
from floating point to integer - will be considered, the compiler will try
to find a floating point conversion. It is actually capable of doing this
even if the types are of a different size like double and float. In the case
that the value can be represented by the new type no change occurs,
otherwise rounding and a loss of precision will take place and the compiler
might give you a warning.


Cheers
Chris

Hi Chris.

I was wrong when I tried given example, because I have created pointer
to instance of B, but I have assigned it to type of A*:

A* obj = new B(); // In given example was B* obj = ...
obj->test(2,3);
obj->test(2.3,2.5); // ###

But anyway. The line marked ### is ambiguous. At least for gcc 4.1.0 on
linux, gcc 3.4.4 on windows, MS Visual Studio .NET 2003, MS Visual
Studio 2005 and Borland C++ 5.5. All of these compilers complain
something like:
main.cpp:38: error: call of overloaded `test(double, double)' is
ambiguous
main.cpp:9: note: candidates are: virtual int A::test(int, int)
main.cpp:15: note: virtual float A::test(float, float)

And I think they are right, because conversion from double to float has
the same priority as conversion from double to int. Compiler does not
care, where is bigger lost of precision.

Correct version of first question example is

#include <iostream>

using namespace std;

class A
{
public:
int virtual test(int a, int b)
{
cout<<"inside A::test(int,int)\n";
return a+b;
}

float virtual test(float a, float b)
{
cout<<"inside A::test(float,float)\n";
return a+b;

}

};

class B : public A
{
public:
using A::test;

int test(int a, int b)
{
cout<<"inside B::test(int,int)";
return a + b;

}
};

int main()
{
B* obj = new B(); // In given example was B* obj = ...
obj->test(2,3); //this wrks fine
obj->test(2.3f, 2.5f);
}

Best Regards,
Ondra
 
C

Chris Theis

[SNIP]
A* obj = new B(); // In given example was B* obj = ...
obj->test(2,3);
obj->test(2.3,2.5); // ###

But anyway. The line marked ### is ambiguous. At least for gcc 4.1.0 on
linux, gcc 3.4.4 on windows, MS Visual Studio .NET 2003, MS Visual
Studio 2005 and Borland C++ 5.5. All of these compilers complain
something like:
main.cpp:38: error: call of overloaded `test(double, double)' is
ambiguous
main.cpp:9: note: candidates are: virtual int A::test(int, int)
main.cpp:15: note: virtual float A::test(float, float)

And I think they are right, because conversion from double to float has
the same priority as conversion from double to int. Compiler does not
care, where is bigger lost of precision.

You're of course right as there is no promotion but rather a "real"
conversion involved. I'm sorry that I didn't think of that while writing my
previous post.

Cheers
Chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,053
Latest member
BrodieSola

Latest Threads

Top