精华内容
下载资源
问答
  • 虚函数打印-单继承函数覆盖 struct func1 { public: virtual void Box1() { printf("Box1\n"); } virtual void Box2() { printf("Box2\n"); } }; struct func2 : func1 { public: virtual void Box3() ...

    虚函数打印-单继承无函数覆盖

    struct func1
    {
    public:
    	virtual void Box1() {
    		printf("Box1\n");
    	}
    	virtual void Box2() {
    		printf("Box2\n");
    	}
    
    };
    
    struct func2 : func1
    {
    public:
    	virtual void Box3() {
    		printf("Box3\n");
    	}
    	virtual void Box4() {
    		printf("Box4\n");
    	}
    };
    
    
    int main()
    {
    	func2 f2;
    	printf("F2的sizeof:%d",sizeof(f2));
    	//虚函数首地址为:*(int*)(*(int*)&f2),其中(*(int*)&f2)就是虚函数表的地址,那么再来一个*(int*)就是取虚函数表地址里的首地址了
    	typedef void(*pfun)(void);
    	pfun p;
    	printf("虚函数表地址为:%#x\n", *(int*)&f2);
    	for (int i = 0; i < 4; i++) {
    		p = (pfun)*((int*)(*(int*)&f2)+i);
    		printf("虚函数地址:%#x----", *((int*)(*(int*)&f2)+i));
    		p();
    	}
    	getchar();
        return 0;
    }
    
    展开全文
  • 继承函数覆盖 struct Base1 { public: virtual void Fn_1() { printf("Base1:Fn_1...\n"); } virtual vo...
    								
    	多继承有函数覆盖							
    								
    	struct Base1							
    	{							
    	public:							
    	    virtual void Fn_1()							
    	    {							
    	        printf("Base1:Fn_1...\n");							
    	    }							
    	    virtual void Fn_2()							
    	    {							
    	        printf("Base1:Fn_2...\n");							
    	    }							
    	};							
    	struct Base2							
    	{							
    	public:							
    	    virtual void Fn_3()							
    	    {							
    	        printf("Base2:Fn_3...\n");							
    	    }							
    	    virtual void Fn_4()							
    	    {							
    	        printf("Base2:Fn_4...\n");							
    	    }							
    	};							
    	struct Sub:Base1,Base2				
    	{							
    	public:							
    	    virtual void Fn_1()							
    	    {							
    	        printf("Sub:Fn_1...\n");							
    	    }							
    	    virtual void Fn_3()							
    	    {							
    	        printf("Sub:Fn_3...\n");							
    	    }							
    		virtual void Fn_5()						
    	    {							
    	        printf("Sub:Fn_5...\n");							
    	    }							
    	};							
    	int main(int argc, char* argv[])							
    	{							
    		//查看 Sub 的虚函数表						
    	    Sub sub;							
    								
    		//通过函数指针调用函数,验证正确性						
    	    typedef void(*pFunction)(void);							
    								
    								
    		//对象的前四个字节是第一个Base1的虚表						
    		printf("Sub 的虚函数表地址为:%x\n",*(int*)&sub);						
    								
    		pFunction pFn;						
    								
    		for(int i=0;i<6;i++)						
    		{						
    			int temp = *((int*)(*(int*)&sub)+i);					
    			if(temp == 0)					
    			{					
    				break;				
    			}					
    			pFn = (pFunction)temp;					
    			pFn();					
    		}						
    								
    		//对象的第二个四字节是Base2的虚表						
    		printf("Sub 的虚函数表地址为:%x\n",*(int*)((int)&sub+4));						
    								
    		pFunction pFn1;						
    								
    		for(int k=0;k<2;k++)						
    		{						
    			int temp = *((int*)(*(int*)((int)&sub+4))+k);					
    			pFn1 = (pFunction)temp;					
    			pFn1();					
    		}						
    								
    		return 0;						
    	}
    

    上面示例代码中,子类sub的sub:Fn_1、sub:Fn_3、sub:Fn_5,与父类base1、base2,先覆盖,后继承,也就是说编译器第一步,会先用子类和所有的父类的比较,有相同的就会把子类虚函数覆盖到父类虚表中。第二步,注意,不相同的子类虚函数会贴在第一个父类虚表后面的位置。

    1.平时不建议使用多继承,代码的维护会比较麻烦,尽量使用多重继承。

    2.多继承有时,除了子类继承第一个父类虚表外,其它继承过来的父类都会单独有一张虚表,也就是虚表会有多个。

    3.有覆盖多继承时,子类的虚函数覆盖哪个父类的虚函数,就存在哪个父类的虚表中。(子类虚函数覆盖哪个父类,就在哪个父类的虚表中)。


    展开全文
  • 继承中的函数覆盖

    2013-07-08 16:24:42
    分俩种情况来考虑: ... 只用函数在基类中被声明为虚函数,那么任何通过基类类型的指针对该函数的调用都是合法的,至于调用的是基类中还是派生类中的函数,则依具体情况。  举例: class Base{  public:

    分俩种情况来考虑:

    1,虚函数。

              只用函数在基类中被声明为虚函数,那么任何通过基类类型的指针对该函数的调用都是合法的,至于调用的是基类中还是派生类中的函数,则依具体情况。

                   举例: class Base{

                               public:

                                         virtual int fcn();

                               };

                               class D1:public Base{

                               public:

                                        //hides fcn in the base;this fcn is not virtual

                                        int fcn(int);        //parameter list differs from fan in Base

                                        //D1 inherits definition of Base::fcn()

                                };

                                class D2:public D1{

                                public:

                                         int fcn(int);        //nonvirtual function hides D1::fcn(int)

                                         int fcn();            //redefines virtual fan from Base

                                };

     

                               Base bobj;  D1 d1obj;   D2 d2obj;

                               Base *bp1 = &bobj,  *bp2 = &d1obj,  *bp3 = &d2obj;

                               bp1->fun();           //ok:virtual call,will call Base::fcn at run time

                               bp2->fun();           //ok:virtual call,will call Base::fcn at run time

                               bp3->fun();           //ok:virtual call,will call D2::fcn at run time

           

    2,非虚函数。

              在基类和派生类中使用同一名字的成员函数,其行为与数据成员一样:在派生类作用域中派生类成员将屏蔽基类成员。即使函数原型不同,基类成员也会被屏蔽。

                   举例:class Base{

                                   int memfun();

                               };

                               class Derived : public Base{

                                        int memfun(int);       //hides memfun in the base

                               };

     

                               Derived d;   Base b;

                               b.memfcn();                   //calls Base::memfcn

                               d.memfcn(10);               //calls Derived::memfun

                               d.memfcn();                   //error:memfcn with no arguments is hidden

                               d.Base::memfcn();         //ok:calls Base::memfcn

    展开全文
  • //多继承(有虚函数覆盖) //1) 每个父类都有自己的虚表,有多少个父类就有多少个虚指针 //2) 子类的所有虚函数地址被放到了第一个父类的虚函数表中(排列顺序:先基类虚函数地址后子类虚函数地址,若覆盖了第一个...
    #include <iostream>
    #include <string>
    #include <vector>
    #include <cctype>
    using namespace std;
    //多继承(有虚函数覆盖)
    //1) 每个父类都有自己的虚表,有多少个父类就有多少个虚指针
    //2) 子类的所有虚函数地址被放到了第一个父类的虚函数表中(排列顺序:先基类虚函数地址后子类虚函数地址,若覆盖了第一个父类中的虚函数,
          则地址变为派生类override的虚函数地址;若没有覆盖,则仍未原父类虚函数地址)。(所谓的第一个父类是按照声明顺序来判断的)
    //3)  若子类override了第二个及其之后的基类的虚函数,则在第二个vftp及之后的 vftp所对应的虚函数表中更改派生类override的虚函数地址。
    //图片中红色标出的虚函数为派生类新增的,放在第一个虚函数表尾部;蓝色标出的为派生类覆盖基类的虚函数
    
     class Base1
    {
    public:
    	int x1;
    	virtual void f1(){cout << "Base1::f" << endl;}
    	virtual void g1(){cout << "Base1::g" << endl;}
    
    };
    
    class Base2
    {
    public:
    	int x2;
    	virtual void f2(){cout << "Base2::f" << endl;}
    	virtual void g2(){cout << "Base2::g" << endl;}
    
    };
    
    class Base3
    {
    public:
    	int x3;
    	virtual void f3(){cout << "Base3::f" << endl;}
    	virtual void g3(){cout << "Base3::g" << endl;}
    
    };
    
    
    
    class Derive:public Base1,public Base2,public Base3
    {
    public:
    	int y;
    	virtual void f(){cout << "Derive::f" << endl;}    //新增f
    	virtual void g1(){cout << "Derive::g1" << endl;}  //覆盖Base1的g1
    
    	//virtual void f2(){cout << "Derive::f2" << endl;}  //覆盖Base2的f2
    
    	virtual void g3(){cout << "Derive::g3" << endl;}  //覆盖Base3的g3
    
    	virtual void myfun1(){cout << "Derive::myfun1" << endl;}    //新增myfun1
    	virtual void myfun2(){cout << "Derive::myfun2" << endl;}    //新增myfun2
    
    };
    
    typedef void (*Fun)();
    
    int main()
    {
    	Fun pFun;
    
    
    	Derive derive;
    	Derive *de = &derive;
    
    	//通过获取private虚函数指针,如下((Fun)((*q)[3]))实现访问!
    	void*** q1 = (void***)&derive;  
    
    	cout<<*q1<<endl;    // Base1Subobj 的 vptr,即指向Base1的虚函数表;
    	cout<<**q1<<endl;   // 没有覆盖,指向Base1的f1虚函数
    	cout<<*(*q1+1)<<endl;  // 覆盖基类g1,指向Derive的g1虚函数
    	cout<<*(*q1+2)<<endl;  // 指向Derive新增的f虚函数
    	cout<<*(*q1+3)<<endl;  // 指向Derive新增的myfun1虚函数
    	cout<<*(*q1+4)<<endl;  // 指向Derive新增的myfun2虚函数
    
    	pFun = (Fun)(**q1);  //pFun为指向Base1::f1()的指针
    	pFun();
    	pFun = (Fun)(*(*q1+1));  //pFun为指向Derive::g1()的指针
    	pFun();
    	pFun = (Fun)(*(*q1+2));   //pFun为指向Derive::f()的指针
    	pFun();
    	pFun = (Fun)(*(*q1+3));   //pFun为指向Derive::myfun1的指针
    	pFun();
    	pFun = (Fun)(*(*q1+4));   //pFun为指向Derive::myfun2的指针
    	pFun();
    
    	system("pause");
    	return 0;
    }
    

    展开全文
  • //单一继承下有虚函数覆盖 //派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。 //虚函数表中按照基类虚函数(若派生类override基类的虚函数,则虚函数表中原先存放的基类虚函数的地址变为相应...
  • c++继承中的函数覆盖规则

    千次阅读 2014-02-12 09:47:45
    问题:如果如图的继承方式,类B会不会自己复制一个和类A一模一样的test函数呢?   测试数据:   #include usingnamespace std; class A { public: void test(){ static int a=1; cout; } }; classB:...
  • //多继承(无虚函数覆盖) //1) 每个父类都有自己的虚表,有多少个父类就有多少个虚指针 //2) 子类的虚函数地址被放到了第一个父类的虚函数表中(排列顺序:先基类虚函数地址后子类虚函数地址)。(所谓的第一个...
  • 【VC++】虚函数 内存结构 - 第五篇(多重继承,有虚函数覆盖
  • 【VC++】虚函数 内存结构 - 第四篇(多重继承,无虚函数覆盖
  • 在之前的博客中有简单的介绍了一下:没有虚函数的菱形继承。此篇博客将对菱形继承进行升级,介绍有虚函数的菱形继承。 举一个简单的例子: #include using namespace std; class AA { public: virtual void fun...
  • 继承&成员函数&覆盖

    2018-01-17 22:43:00
    //成员函数。 /* 当子父类中出现成员函数一模一样的情况,会运行子类的函数。 这种现象,称为覆盖操作。这时函数在子父类中的特性。 函数两个特性: 1,重载。同一个类中。overload 2,覆盖。子类中。覆盖也...
  • //单一继承下无虚函数覆盖 //派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。虚函数表中按照基类虚函数、派生类新增的虚函数顺序依次排列。 //要注意的是一旦将指针p转换成void*(或void**...
  • public继承是一种is-a关系。也就是说适用于base classes(基类)身上的每一件事都一定适用于derived classes(继承类),每一个derived classes对象都是一个derived classes对象。 class A{ void func(); ... } ...
  • struct: 默认public(结构体是一种特殊的类) class: 默认private 数据成员和成员函数对外不能被访问 在c++中结构体和类是...每个类都必须有一个构造函数,如果自己没有写,那么c++会提供一个默认的构造函数用于创
  • //单一继承下无虚函数覆盖 //派生类只有一个虚函数表,派生类对象只有一个虚指针来指向这个虚函数表。虚函数表中按照基类虚函数、派生类新增的虚函数顺序依次排列。 //直接使用三级指针,第二次解引用时可以直接...
  • 函数覆盖

    2016-04-04 14:40:53
    函数覆盖只能发生在父类和子类之间//继承includeusing namespace std; class animal { public: animal(int hight, int weight) { //cout “animal construct” ; } ~animal() {
  • 【VC++】虚函数 内存结构 - 第三篇(单继承,有虚函数覆盖) #include <IOSTREAM> using namespace std; class Base { public: int nBase1; int nBase2; Base(int n1,int n2):nBase1(n1),nBase2(n2) { ...
  • 【VC++】虚函数 内存结构 - 第二篇(单继承,无虚函数覆盖) #include <IOSTREAM> using namespace std; class Base { public: int nBase1; int nBase2; Base(int n1,int n2):nBase1(n1),nBase2(n2) { ...
  • 问题描述: 下面的代码试图去通过运行时程序分析和验证C++的虚表实现机制。...这样以来,基类的函数实现就会被覆盖。通过虚表调用函数f,都会调用重新定义的这个,而不是旧的(实质是指针的覆盖)。 但
  • 方法重载,指的是同名函数,用不同的参数,即可以实现两个函数功能 记住啊,兄弟们,一个类中不能同时存在两个一模一样的方法名,但是两个类中可以哈(存在相同的可以哈) php没有方法重载,为什么? 代码演示把,兄弟...
  • //父类的Print是虚函数,继承的时候被子类的Print函数覆盖 cin >> type >> color >> daytime; Bird bird(type, color, daytime); bird.Print(); animal = &bird; animal->Print(); return 0; }
  • 一、 C++成员函数的重载 C++中的成员函数有四种,分别是普通成员函数,virtual虚函数,const成员函数。 (1) void func(int a); (2) virtual void func(int a); (3) void func(int a) const; 如果在一个类中,...
  • 继承方式与访问属性 访问控制属性决定了成员的访问范围: public 可以在任何位置访问 private 只能在类内访问 protected 只能在类内和子类中访问 继承方式的影响: 1、父类的成员能否在子类中访问,是设计父类时...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,039
精华内容 1,615
关键字:

继承函数覆盖