虚函数查找的规则是什么?

发布于 2024-10-25 08:38:14 字数 778 浏览 1 评论 0原文

#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 << "derived\n";
    }   
};

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

    return 0;
}

该函数的输出是:

base
a: 10000 base
  • Why b->print (d) don't invoke the导出类实现并且 对 'd' 执行静态转换以提供与基类的匹配 执行 ?
  • 在虚函数查找期间应用什么规则?
#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 << "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 ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

玩世 2024-11-01 08:38:14

衍生::打印不会覆盖base中的任何成员函数。它被声明为具有 double 类型的单个参数,但 base 中名为 print 的两个虚拟成员函数被声明为具有一个和两个参数int 类型。

当您使用b->print(d)时,在重载解析期间仅考虑base中的成员函数,因此仅void base::print(int)考虑void base::print(int, int) 。无法找到 void衍生::print(double),因为编译器不知道b指向衍生对象。

如果衍生要重写在base中声明为虚拟成员函数的两个print函数之一,则该重写将在运行时调用。

(在某种程度上相关的说明中,派生::print 隐藏了两个基类::print 成员函数,因此如果您尝试使用基类之一print 函数,例如 衍生().print(1, 1),它会失败。您需要使用 using 声明来使这些成员函数在名称查找期间可用。 )

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

倚栏听风 2024-11-01 08:38:14

重载解析发生在编译时。覆盖发生在运行时。

因此,b->print(d); 的重载决策首先发生。这会选择Base::print(int),因为它是唯一的一个参数print

在运行时,b 指向一个 Derived 对象,该对象没有覆盖 Base::print(int)。因此,Base::print(int) 仍然被调用。

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.

御弟哥哥 2024-11-01 08:38:14

因为 double 可以在它看到的第一个定义(在基类中)中自动转换为 int

请参阅 explicit 关键字或 这个问题

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文