C++ 静态函数和非虚拟方法可以被重写吗?什么是静态多态性?
请参阅此函数的输出。它显示可以重写静态函数,因为派生类继承函数:C++ 静态函数和非虚拟方法可以被重写吗?什么是静态多态性?,c++,inheritance,static,polymorphism,virtual,C++,Inheritance,Static,Polymorphism,Virtual,请参阅此函数的输出。它显示可以重写静态函数,因为派生类继承函数: void put(){printf("Static functions in base class");} 如果我们不重写put()输出是基类中的静态函数 但我们将其改写为: void put(){printf("Static functions are overridden in derived class");} 所以输出是静态的,函数在派生类中被重写 公众: #包括 阶级基础{ 公众: 静态void put(){prin
void put(){printf("Static functions in base class");}
如果我们不重写put()
输出是基类中的静态函数
但我们将其改写为:
void put(){printf("Static functions are overridden in derived class");}
所以输出是静态的,函数在派生类中被重写
公众:
#包括
阶级基础{
公众:
静态void put(){printf(“基类中的静态函数”);}
};
派生类:公共基{
void put(){printf(“静态函数在派生
类“;}
};
int main(){
派生的*bp=新派生的;//静态多态性//
bp->put();
返回0;
}
因为这里的put()
不是一个虚拟函数。那么,我们可以覆盖非虚拟函数吗
这是静态多态的情况吗 不,这不是静态多态的情况:这里没有“覆盖”,因为函数调用在编译时被完全解析 编译器知道
bp
的类型是derived*
,因此它调用静态成员函数derived::put
。如果bp
的编译时类型是base*
,则会调用base::put
:
这就是为什么通过实例指针调用静态函数具有误导性。代码中的调用相当于
派生::put()
,但是代码的读取器必须跟踪声明的类型才能看到它。否。静态成员函数和非虚拟成员函数都不能被重写
对于您的情况,如果您将bp
的类型更改为base*
,您将看到结果将是
Static functions in base class
无法重写静态成员函数,它们的行为类似于自由函数,不依赖于对象,不隐式使用此
指针。将调用哪个函数取决于静态类型
静态函数可以被重写吗
没有
Base::f
和Derived::f
是两个不同的函数,它们甚至不共享一个公共接口:property不接受任何参数,后者是指向派生的
的隐藏指针
是否可以重写非虚拟函数
没有
Derived::f
在操作对象、对象引用或指向类型为Derived
的对象的指针时,隐藏Base::f
:
Derived d;
Derived& dref = d;
Derived* dptr = &d;
d.f(); // calls Derived::f
dref.f(); // calls Derived::f
dptr->f(); // calls Derived::f
Base& bref = d;
Base* bptr = &d;
bref.f(); // calls Base::f
bptr ->f(); // calls Base::f
我看不出这里的多态性。如果您执行
base*bp=新派生;bp->put()代码>它将调用base::put()
(即无多态性)。先生,隐藏从基类继承的函数和重写从基类继承的函数有什么区别?@VinayakSangar在第二种情况下,如果base::f
(因此Derived::f
)是virtual
,bref.f()
和bptr->f()
将调用Derived::f
。
Static functions in base class
struct Base { static void f() {} };
struct Derived : Base { void f() {} };
struct Base { void f() {} };
struct Derived : Base { void f() {} };
Derived d;
Derived& dref = d;
Derived* dptr = &d;
d.f(); // calls Derived::f
dref.f(); // calls Derived::f
dptr->f(); // calls Derived::f
Base& bref = d;
Base* bptr = &d;
bref.f(); // calls Base::f
bptr ->f(); // calls Base::f