C++ c++;多态性,派生类的名称解析 类基{ 公众: 虚空f(float){coutf(3.14F); }

C++ c++;多态性,派生类的名称解析 类基{ 公众: 虚空f(float){coutf(3.14F); },c++,polymorphism,object-slicing,C++,Polymorphism,Object Slicing,-C++不支持contravaraint返回类型,因此f(int)不重写f(float) 多态性由C++支持,所以D和B都应该指向派生类的VTABLE。 -派生类的vtable类似于0:f(float)、1:f(int)等 我的答案是Base::f(float)调用了两次,但答案是: 基::f(浮点)派生::f(int) 为什么会这样?从不同的指针访问派生类是否强制执行某些规则?据我所知,对象切片仅在使用复制选择器或复制赋值时发生,对于指针,它们都应该指向同一个vtable。不同类中的方法不会一

-C++不支持contravaraint返回类型,因此f(int)不重写f(float)

多态性由C++支持,所以D和B都应该指向派生类的VTABLE。 -派生类的vtable类似于0:f(float)、1:f(int)等

我的答案是Base::f(float)调用了两次,但答案是:

基::f(浮点)派生::f(int)


为什么会这样?从不同的指针访问派生类是否强制执行某些规则?据我所知,对象切片仅在使用复制选择器或复制赋值时发生,对于指针,它们都应该指向同一个vtable。

不同类中的方法不会一起重载;定义另一个
f()
Derived
中的
防止在重载解析过程中考虑
Base中的

如果要添加新的重载而不隐藏在基类中定义的重载,则需要显式地将基类定义引入派生类

class Base {
public:
virtual void f(float) { cout << "Base::f(float)\n"; }
};
class Derived : public Base {
public:
virtual void f(int) { cout << "Derived::f(int)\n"; }
};
int main() {
Derived *d = new Derived();
Base *b = d;
b->f(3.14F);
d->f(3.14F);
}

我的看法是,当调用
d->f(3.14F)

您的
派生类实际上有两个f()条目

这在带有-fdump class hierarchy标志的g++中得到了确认。我们可以看到如下输出:

void f(int);
void f(float);
由于定义不匹配,
派生的
类未触及基类中的f函数。由于浮点和int之间存在隐式转换,因此代码可以编译

试试下面的方法

Vtable for Base
Base::_ZTV4Base: 3u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI4Base)
8     (int (*)(...))Base::f

Vtable for Derived
Derived::_ZTV7Derived: 4u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI7Derived)
8     (int (*)(...))Base::f
12    (int (*)(...))Derived::f
派生类:公共基{
公众:

虚空f(std::string){coutf(3.14F)将在基表中解析,d->f(3.14F)将使用隐藏基的派生表进行解析。

为什么
Base->f
引用基函数?我还很好奇指针如何影响名称解析。@0x499602D2因为它是通过指向-
Base
的指针访问的,所以编译器在执行超负荷分辨率。过载解决在编译时发生,而不是在运行时。回过头来看,我意识到重写没有发生,应该是显而易见的,因为C++不支持逆变参数!
Vtable for Base
Base::_ZTV4Base: 3u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI4Base)
8     (int (*)(...))Base::f

Vtable for Derived
Derived::_ZTV7Derived: 4u entries
0     (int (*)(...))0
4     (int (*)(...))(& _ZTI7Derived)
8     (int (*)(...))Base::f
12    (int (*)(...))Derived::f
class Derived : public Base {
public:
virtual void f(std::string) { cout << "Derived::f(string)\n"; }
};