virtual functions in inherited class

Discussion in 'C++' started by vabby, Dec 15, 2006.

  1. vabby

    vabby Guest

    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
    vabby, Dec 15, 2006
    #1
    1. Advertising

  2. vabby

    Ondra Holub Guest

    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);

    >
    > 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
    Ondra Holub, Dec 15, 2006
    #2
    1. Advertising

  3. vabby wrote:
    > 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
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 15, 2006
    #3
  4. vabby

    vabby Guest

    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);
    vabby, Dec 15, 2006
    #4
  5. vabby

    Salt_Peter Guest

    vabby wrote:
    > 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
    }
    Salt_Peter, Dec 15, 2006
    #5
  6. vabby

    Chris Theis Guest

    "Ondra Holub" <> wrote in message
    news:...
    >
    > 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);


    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
    Chris Theis, Dec 15, 2006
    #6
  7. vabby

    Ondra Holub Guest

    Chris Theis napsal:
    > "Ondra Holub" <> wrote in message
    > news:...
    > >
    > > 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);

    >
    > 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
    Ondra Holub, Dec 15, 2006
    #7
  8. vabby

    Chris Theis Guest

    "Ondra Holub" <> wrote in message
    news:...
    [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
    Chris Theis, Dec 16, 2006
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bint
    Replies:
    3
    Views:
    348
  2. Replies:
    7
    Views:
    376
    Richard
    Aug 28, 2006
  3. John Goche
    Replies:
    10
    Views:
    735
    Marcus Kwok
    Dec 8, 2006
  4. Angus
    Replies:
    5
    Views:
    1,394
    Krice
    Apr 10, 2008
  5. 7stud --
    Replies:
    11
    Views:
    394
    7stud --
    Nov 9, 2007
Loading...

Share This Page