C++基类与派生类的函数调用情况

xiaoxiao2021-02-28  95

在定义了基类的指针与派生类的对象,或者是派生类指针与基类的对象。

在函数调用的时候,如果该函数在基类中被定义为虚函数,那么在调用的时候看该指针(包括基类指针和派生类指针)所指向的对象,如果是派生类的对象就调用派生类中重写的函数,如果是基类的对象就调用基类中的函数。如果该函数为非虚函数,那么看该指针的类型,如果是基类的指针就调用基类中的函数,如果是派生类的指针就调用派生类中的函数。这种情况是非多态的情况,函数没有实现重写,而只是进行了覆盖。

#include "iostream" using namespace std; #include<iostream> using namespace std; class Base { public: virtual void f(float x) { cout<<"Base::f(float)"<< x <<endl; } void g(float x) { cout<<"Base::g(float)"<< x <<endl; } }; class Derived : public Base { public: virtual void f(float x) { cout<<"Derived::f(float)"<< x <<endl; //多态、覆盖 } void g(int x) { cout<<"Derived::g(int)"<< x <<endl; //隐藏 } }; int main(void) { //定义子类的对象 Derived d; // 基类的指针指向子类对象 Base *pb = &d; //子类指针指向子类对象 Derived *pd = &d; //虚函数,是调用所指向对象的函数 pb->f(3.14f); // Derived::f(float) 3.14 pd->f(3.14f); // Derived::f(float) 3.14 // 非虚函数,根据指针属于基类或子类调用 pb->g(3.14f); // Base::g(float) 3.14 pd->g(3.14f); // Derived::g(int) 3 Base a;//定义基类的对象 Derived *ptr = (Derived *)&a;//子类的指针 ptr->f(3.14f); // Base::f(float) 3.14 ptr->g(3.14f); // Derived::g(int) 3 return 0; } #include <iostream> using namespace std; class Contained1 { public: Contained1() { cout << "Contained1 constructor." << endl; } ~Contained1(){ cout << "Contained1 destructor." << endl; } }; class Contained2 { public: Contained2() { cout << "Contained2 constructor." << endl; } ~Contained2(){ cout << "Contained2 destructor." << endl; } }; class Contained3 { public: Contained3() { cout << "Contained3 constructor." << endl; } ~Contained3(){ cout << "Contained3 destructor." << endl; } }; class BaseContainer { public: BaseContainer() { cout << "BaseContainer constructor." << endl; } // virtual destructor is very important here, or will cause resources leak. virtual ~BaseContainer(){ cout << "BaseContainer destructor." << endl; } private: Contained1 c1; Contained2 c2; }; class DerivedContainer : public BaseContainer { public: DerivedContainer(){ cout << "DerivedContainer constructor." << endl; } ~DerivedContainer(){ cout << "DerivedContainer destructor." << endl; } private: Contained3 c3; }; int main() { DerivedContainer dc; cout << "+++++++++++++" << endl; BaseContainer *p = new DerivedContainer(); cout << "*************" << endl; /* * If baseContainer destructor is not virtual, delete p has undefined behaviour. * In most implementations, the call to the destructor will be resolved like any non-virtual code, * meaning that the destructor of the base class will be called but not the one of the derived class, * resulting in a resources leak. * Refer to: * http://stackoverflow.com/questions/461203/when-to-use-virtual-destructors */ delete p; cout << "-------------" << endl; return 0; // Here dc is destroyed normally no matter whether the base class's destructor is virtual or not. }
转载请注明原文地址: https://www.6miu.com/read-34664.html

最新回复(0)