开发者

What are the rules for virtual function lookup?

开发者 https://www.devze.com 2023-02-17 20:43 出处:网络
#include <iostream> class base { public: virtual void print (int a) { std::cout << \"a: \" << a << \" base\\n\";
#include <iostream>
class base
{
    public:
    virtual void print (int a)
    {   
        std::cout << "a: " << a << " base\n";
    }   
    virtual void print (int a, int b)
    {   
        std::cout << "base\n";
    }   
};

class derived : public base
{
    public:
    virtual void print (double d)
    {   
        std::cout <&l开发者_运维问答t; "derived\n";
    }   
};

int main ()
{
    int i = 10; 
    double d = 10000.0;
    base *b = new derived (); 
    b->print (i, i); 
    b->print (d);

    return 0;
}

The output of this function is:

base
a: 10000 base
  • Why b->print (d) don't invoke the derived class implementation and performs static cast on 'd' to provide a match with base class implementation ?
  • What rule is applied here during virtual function lookup ?


derived::print does not override any member function in base. It is declared as having a single parameter of type double but the two virtual member functions named print in base are declared as having one and two parameters of type int.

When you use b->print(d), only member functions in base are considered during overload resolution, so only void base::print(int) and void base::print(int, int) are considered. void derived::print(double) can't be found because the compiler has no idea that b points to a derived object.

If derived were to override one of the two print functions declared as virtual member functions in base, then that override would be called at runtime.

(On a somewhat related note, derived::print hides the two base::print member functions, so if you were to try to use one of the base class print functions, e.g., derived().print(1, 1), it would fail. You would need to use a using declaration to make those member functions available during name lookup.)


Overload resolution happens at compile time. Overrides happen at run time.

Therefore, the overload resolution of b->print(d); happens first. This selects Base::print(int) because it's the only one-argument print.

At runtime, b points to a Derived object that has no override for Base::print(int). Therefore, Base::print(int) is still called.


Because double can be automatically converted to an int in the first definition it sees (in the base class)

See explicit keyword or this question

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号