/*
关于C++的隐藏规则:
我曾经听说C++的隐藏规则
*/
#include <iostream>
using namespace std;
class Base
{
public:
virtual void f(float x) { cout << "Base::f(float) \t" << x << endl << endl; }
void g(float x) { cout << "Base::g(float) \t" << x << endl << endl; }
void h(float x) { cout << "Base::h(float) \t" << x << endl << endl; }
};
class Derived:public Base
{
public:
virtual void f(float x) { cout << "Derived::f(float) \t" << x << endl << endl; }
void g(int x) { cout << "Derived::g(int) \t" << x << endl << endl; }
void h(float x) { cout << "Derived::h(int) \t" << x << endl << endl; }
};
void main(void)
{
Derived d;
Base *pb = &d;
Derived *pd = &d;
// Good:behavior depends solely on type of the object
pb->f(3.13f); // Derived::f(float) 3.14
pb->f(3.14f); // Derived::f(float) 3.14
// Bad: behavior depends on type of the pointer
pb->g(3.14f); // Base::g(float) 3.14
pd->g(3.14f); // Derived::g(int) 3 (surprise)
// Bad: behavior depends on type of the pointer
pb->h(3.14f); // Base::h(float) 3.14(surprise)
pd->h(3.14f); // Derived::h(int) 3.14
}
/*
pb 和 pd 指向同一地址,按理说运行结果是相同的,而事实上运行结果不同,所以他把原因归结为C++
的隐藏规则,其实这一观点是错误的。决定pb和pd调用函数运行结果的不是他们指向的地址,而是他们的指针类型。
“只有在通过基类指针或引用间接指向派生类子类型时多态性才会起作用”(C++ primer 3rd Edition)。
pb是基类指针,pd是派生类指针,pd的所有函数调用都只是调用自己的函数,和多态性无关,所以pd的所有
函数调用的结果都是Derived::是完全正常的;
pb的函数调用如果与virtual则根据多态性调用派生类的,如果没有virtual则是正常的静态函数调用,
还是调用基类的,所以有virtual的f函数调用输出Derived::,其他两个没有virtual则还是输出Base::很正常啊,
nothing surprise!
所以并没有所谓的隐藏规则,虽然《高质量C++/C编程指南》是本不错的书,可大家不要迷信哦,记住“至于在
通过基类指针或引用间接指向派生类子类型时多态性才会起作用”。
*/
【C++】 类中virtual详解2
最新推荐文章于 2023-05-22 19:36:33 发布