zoukankan      html  css  js  c++  java
  • 关于C++与Java中虚函数问题的读书笔记

              之前一直用C++编程,对虚函数还是一些较为肤浅的理解。可近期由于某些原因搞了下Java,发现有些知识点不熟,于是站在先驱巨人的肩上谈谈C++与Java中虚函数问题。

    Java中的虚函数

              以下是段别人的代码,输入结果竟是Base,这让一直以来用C/C++的我有些莫不着头脑,不是Java里对象是引用吗?C/C++中通过指向基类的指针或引用来指向派生类,那么对于虚函数来说通过基类指针使用的是指向的派生类。但在Java中没有keyword标明虚函数,此时就不是非常明确究竟调用的谁。

    class base
    {
        private void print()
        {
             System.out.println("base");
        }
        public void doprint()
        {
             print();
        }
    }
    
    class derive extends base
    {
        private void print()
        {
             System.out.println("derive");
        }
    }
    
    class testVirtual
    {
        public static void main(String args[])
        {
             base b = new derive();
             b.doprint();
        }
    
    
    
    }
    
    

              而以下这段Java输出的是derived,注意函数以及訪问权限的变化。

    class base
    {
        public void print()
        {
             System.out.println("base");
        }
        public void doprint()
        {
             print();
        }
    }
    
    class derive extends base
    {
        public void print()
        {
             System.out.println("derive");
        }
    }
    
    class testVirtual
    {
        public static void main(String args[])
        {
             base b = new derive();
             b.print();
        }
    }
    
    

             大牛甲如是说:“java里的protected,public,包訪问级别的函数都是虚函数。”也有大牛乙如是说:“java里的都是虚函数。”我的解读是这二位大牛的话肯定都对,private级别的函数也能够说是虚函数,仅仅只是基类的引用无法直接訪问派生类的private级别的函数罢了,仅仅能訪问自己的。

          于是能够断定以下这段就是输出derive了。没错,就是这样。

    class base {
     private void print() {
      System.out.println("base");
     }
    
     public void doprint() {
      print();
     }
    }
    
    class derive extends base {
     private void print() {
      System.out.println("derive");
     }
     public void doprint() {
      print();
     }
    }
    
    class testVirtual {
     public static void main(String args[]) {
      base b = new derive();
      b.doprint();
     }
    }
    
    


    C++中的虚函数

           以下这段C++代码输出的是drived,通过基类的指针或引用指向派生类或基类,然后调用二者共同拥有都有的作为虚函数的函数,此时调用的是指针所指向的类(能够是基类也能够是派生类,关键看此时基类的指针或引用指向的是派生类还是基类)。注意仅仅有基类的指针或引用才干实现虚函数有关多态的问题,其它类型在C++中仅仅调用自己的函数。

    #include<iostream>
    using namespace std;
    
    class base
    {
    private:
     virtual void print()
     {
      printf("base
    ");
     } 
    public:
     void doprint()
     {
      print();
     }
     virtual ~base(){}
    };
    
    class derived : public base
    {
     virtual void print()
     {
      printf("derived
    ");
     }
    };
    
    int main(int argc, char* argv[])
    {
     derived d;
     base& b = d;
     b.doprint();
     return 0;
    }
    //也是derived
    #include<iostream>
    using namespace std;
    
    class base
    {
    private:
    	virtual void print()
    	{
    		printf("base
    ");
    	}	
    public:
    	void doprint()
    	{
    		print();
    	}
    	virtual ~base(){}
    };
    
    class derived : public base
    {
    	private:
    	virtual void print()
    	{
    		printf("derived
    ");
    	}
    	public:
    	void doprint()
    	{
    		print();
    	}
    };
    
    int main(int argc, char* argv[])
    {
    	derived d;
    	base& b = d;
    	b.doprint();
    	return 0;
    }
    //输出的是base
    #include<iostream>
    using namespace std;
    
    class base
    {
    private:
    	virtual void print()
    	{
    		printf("base
    ");
    	}	
    public:
    	void doprint()
    	{
    		print();
    	}
    	virtual ~base(){}
    };
    
    class derived : public base
    {
    	private:
    	virtual void print()
    	{
    		printf("derived
    ");
    	}
    	public:
    	void doprint()
    	{
    		print();
    	}
    };
    
    int main(int argc, char* argv[])
    {
    	derived d;
    	base b = d;
    	b.doprint();
    	return 0;
    }


          以下这段输出的就是base了,由于不是虚函数,通过基类的指针或引用调用的就是基类的函数。

    #include<iostream>
    using namespace std;
    
    class base
    {
    public:
    	void print()
    	{
    		printf("base
    ");
    	}	
    	virtual ~base(){}
    };
    
    class derived : public base
    {
    	public:
    	void print()
    	{
    		printf("derived
    ");
    	}
    };
    
    int main(int argc, char* argv[])
    {
    	derived d;
    	base& b = d;
    	b.print();
    	return 0;
    }

             以下C++代码输出的是derived,这就是同名覆盖原则,派生类覆盖积累的同名函数。

    #include<iostream>
    using namespace std;
    
    class base
    {
    public:
    	void print()
    	{
    		printf("base
    ");
    	}	
    	virtual ~base(){}
    };
    
    class derived : public base
    {
    	public:
    	void print()
    	{
    		printf("derived
    ");
    	}
    };
    
    int main(int argc, char* argv[])
    {
    	derived d;
    	base& b = d;
    	d.print();
    	return 0;
    }


    总结对照
    C++                     Java
    虚函数     --------    普通函数
    纯虚函数   --------    抽象函数
    抽象类     --------    抽象类
    虚基类     --------    接口     
          关于虚函数的实现机制,涉及虚函数表等,兴许博客补上。因为理论知识不足,难以上升到详细底层实现,望理解!

     

     

     

     

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    day 67 Django基础三之视图函数
    day 66 Django基础二之URL路由系统
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/3776420.html
Copyright © 2011-2022 走看看