精华内容
下载资源
问答
  • 虚函数可以为private
    千次阅读
    2015-05-26 00:48:05

    C++中,虚函数可以为private,并且可以被子类覆盖。

    例如,下面程序工作正常。

    #include<iostream>
    
    class Base {
    private:
        virtual void fun() { std::cout << "Base Fun" << std::endl; }
        friend int main();
    };
    
    class Derived : public Base {
    public:
        void fun() { std::cout << "Derived Fun" << std::endl; }
    };
    
    int main() {
        Base* ptr = new Derived;
        ptr->fun();
        return 0;
    }

    运行结果:
    Derived fun()

    对于上面的程序,有下面几点是需要注意的方面:
    1) ptr是一个Base类型的指针,指向的是Derived对象。最终实际调用的是Derived::fun()。

    2) int main()是Base类的友元函数。如果删除这个友元声明,则程序会编译失败。因为在编译期间,会进行权限检查。对于这行代码ptr->fun(), 编译器会检查到fun是私有函数,base类型的对象/指针无权访问。

    这种行为与Java完全不同。在Java中,私有方法默认是final的,不能被覆盖。

    更多相关内容
  • C++中虚函数能不能声明为private

    千次阅读 2019-07-13 22:11:12
    如果声明虚函数声明为private时编译会报错,但是还是有手段调用声明为private虚函数的。首先让我们来看看调用声明为private虚函数时会发生什么情况。 #include <iostream> using namespace std; class ...

    如果声明虚函数声明为private时编译会报错,但是还是有手段调用声明为private的虚函数的。首先让我们来看看调用声明为private的虚函数时会发生什么情况。

    #include <iostream>
    
    using namespace std;
    class classB
    {
    private:
    	virtual void fun() { cout << "virtual fun of classB" << endl; }
    	void fun2() { cout << "fun2 of classB" << endl; }
    	//friend int main();
    };
    
    class classA : public classB
    {
    public:
    	virtual void fun() { cout << "virtual fun of classA" << endl; }
    	void fun2() { cout << "fun2 of classA" << endl; }
    
    
    };
    
    
    int main()
    {
    	classB *obj = new classA;
    	obj->fun();
    	obj->fun2();
    	while (1);
    
    	return 0;
    }

     

    那么如何能把虚函数声明为private呢,把要调用该虚函数的函数声明为类的友元函数就行了,让我们看一下。

    #include <iostream>
    
    using namespace std;
    class classB
    {
    private:
    	virtual void fun() { cout << "virtual fun of classB" << endl; }
    	void fun2() { cout << "fun2 of classB" << endl; }
    	friend int main();
    };
    
    class classA : public classB
    {
    public:
    	virtual void fun() { cout << "virtual fun of classA" << endl; }
    	void fun2() { cout << "fun2 of classA" << endl; }
    
    
    };
    
    
    int main()
    {
    	classB *obj = new classA;
    	obj->fun();
    	obj->fun2();
    	while (1);
    
    	return 0;
    }

    可以看到当classA中的虚函数为public是可以这样调用的,但是如果classA中的虚函数声明为private还可以调用吗?让我们来看一下。

    #include <iostream>
    
    using namespace std;
    class classB
    {
    private:
    	virtual void fun() { cout << "virtual fun of classB" << endl; }
    	void fun2() { cout << "fun2 of classB" << endl; }
    	friend int main();
    };
    
    class classA : public classB
    {
    public:
    	
    	void fun2() { cout << "fun2 of classA" << endl; }
    private:
    	virtual void fun() { cout << "virtual fun of classA" << endl; }
    
    };
    
    
    int main()
    {
    	classB *obj = new classA;
    	obj->fun();
    	obj->fun2();
    	while (1);
    
    	return 0;
    }

    可以看到即使classA中的虚函数声明为private时还是可以调用的,这是为什么呢?main又不是classA的友元函数,我个人观点是虚函数是实际上通过classB对象来调用的,如果理解有错麻烦告诉我一下,谢谢!

    展开全文
  •  当我们在程序中声明一个对象时,编译器调用构造函数(如果有的话),而这个调用将通常是外部的,也就是说它不属于class对象本身的调用,假如构造函数是私有的,由于在class外部不允许访问私有成员,所以这将导致...
  • C++之private虚函数

    2018-09-16 23:40:04
    一般我们说虚函数,它的访问级别都是public的,用类对象可以直接调用,这样就可以实现运行时的类型绑定,那如果我们将虚函数私有化会出现什么情况呢? 我们先来看一个非虚函数私有化的例子 class Base { private:...

    一般我们说虚函数,它的访问级别都是public的,用类对象可以直接调用,这样就可以实现运行时的类型绑定,那如果我们将虚函数私有化会出现什么情况呢?

    我们先来看一个非虚函数私有化的例子

    class Base
    {
    private:
        void PrintClassName ()
        {
            cout<<"Base"<<endl;
        }
    public:
        void print()
        {
            PrintClassName();
        }
    };
    
    class Derived : public Base
    {
    private:
        void PrintClassName()
        {
            cout<<"Derived"<<endl;
        }
    };

    在main函数里产生一个Derived的对象d,然后调用print()函数,即d.print(),结果输出的却是Base,print()函数没有调用子类的PrintClassName函数,而是调用父类的PrintClassName函数,原来是由于PrintClassName函数不是虚函数之故,所以Base的print()函数调用PrintClassName()函数是在编译时就已经绑定了,而不是运行期绑定。

    下面我们让PrintClassName()函数变成虚函数再执行,就可以看到输出的类名为子类的名称,即Derived。

    那么我们有没有办法调用私有的虚函数呢?当然是有的,不管公有还是私有,只要是虚函数,它的函数地址都会放在虚函数表vftable中,只要我们找到虚函数表中存放的PrintClassName()函数的地址,我们就可以直接调用,前提是你必须对C++类对象的内存布局要熟悉,代码如下,这样也输出Derived,与前面效果相同

    int _tmain(int argc, _TCHAR* argv[])
    {
        
        Derived d;
        //d.print();
        typedef void (*Fun)();
        Fun pFun = NULL;
        pFun = (Fun)*((int *)(*(int *)&d + 0) + 0);
        pFun();
    
        getchar();
        return 0;
    }
    展开全文
  •   前些天面试,被问到一个很有意思的问题:c++中能否调用protected修饰的虚函数,之前没有尝试过,所以只能靠直觉回答:“在技术上,只要知道虚函数表的地址就可以调用,但是不清楚protected保护的机制是具体在哪...


    本文目的

     
      前些天面试,被问到一个很有意思的问题:c++中能否直接调用protected修饰的虚函数,之前没有尝试过,所以只能靠直觉回答:“在技术上,只要知道虚函数表的地址就可以调用,但是不清楚protected保护的机制是具体在哪一个时期起的作用,可能需要一些手段来绕开这个机制。” 我的回答就是这样(自我感觉回答的还是含糊不清楚,只是概念上推测,没有给出具体的方法)。好心的面试官还是跟我解释了protected是编译器在编译期做检查。所以本文就直接上代码,给出解决此问题的具体的实现。
    (ps:对虚函数表内部结构不明白的可以看我的另一篇文章,C++在gcc下的单继承,多继承,虚继承的内存布局


    代码

    不可行的直接调用

    	    1 #include<iostream>                                                        
        2 
        3 using namespace std;
        4 
        5 typedef void (*Fuc)(void);
        6 
        7 class A{
        8 protected:
        9     virtual void foo()
       10     {
       11         cout<<"A foo"<<endl;
       12     }
       13 private:
       14     virtual void bar()
       15     {
       16         cout<<"A bar"<<endl;
       17     }
       18 };
       19 
       20 int main()
       21 {
       22     A* a = new A; 
       23     a->foo();
       24     a->bar();
       25 }
    

    结果
    在这里插入图片描述
    意料之内的编译错误。


    可行的指针调用

     

      1 #include<iostream>
      2 
      3 using namespace std;
      4 
      5 typedef void (*Fuc)(void);
      6 
      7 class A{
      8 protected:
      9     virtual void foo()
     10     {
     11         cout<<"A foo"<<endl;
     12     }
     13 private:
     14     virtual void bar()
     15     {
     16         cout<<"A bar"<<endl;
     17     }
     18 };
     19 
     20 int main()
     21 {
     22     A* a = new A; 
     23     Fuc fucFoo = (Fuc)*((long*)*(long*)a);
     24     Fuc fucBar = (Fuc)*((long*)*(long*)a+1);
     25     fucFoo();
     26     fucBar();
     27 }      
    

    运行结果:
    在这里插入图片描述
      成功运行,且没有触发编译器的检查(因为就没有调用A的对象,单纯根据虚函数地址通过函数指针调用)。
    (ps:对虚函数表内部结构不明白的可以看我的另一篇文章,C++在gcc下的单继承,多继承,虚继承的内存布局

      


    尾语

      不明白就得动手,不然只能原地打转,处于被动。

    以上

    展开全文
  • 当一个函数是内联和虚函数时,会发生代码替换或使用虚表调用吗? 为了弄清楚内联和虚函数,让我们将它们分开来考虑。通常,一个内联函数是被展开的。 class CFoo { private:  int val; public:  int GetVal...
  • 虚函数用作private会怎样?

    千次阅读 2017-09-04 22:31:59
    2.如果使用指向对象的引用或指针来调用虚函数,程序将使用对象类型定义的方法,而不是使用引用或指针类型定义的方法。这样基类引用或指针就可以指向派生类对象。3.如果定义的类将被用作基类,则应将那些要在派生...
  • 关于虚函数的回顾: 1) :虚函数的地址存放于虚函数表之中。... 3):虚函数的调用会被编译器转换虚函数表的访问 。 当虚函数是public的,这个时候实现多态的方式: class Base { public: virtual...
  • 虚函数为了重载和多态的需要,在基类中是有定义的,即便定义是空,所以子类中可以重写也可以不写基类中的此函数! 纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数! 虚函数 引入原因:...
  • 我们把一个仅仅含有纯虚函数的类...那么,让我们想一想,纯虚函数或者虚函数可以为private吗?如果这种方式是可行的,那么什么时候可以将(纯)虚函数为private了?这些都是本文将要讨论的主题。一起来看看。 一....
  • private虚函数

    千次阅读 2012-05-14 15:13:30
    我们把一个仅仅含有纯虚函数的类称为接口...那么,让我们想一想,纯虚函数或者虚函数可以为private吗?如果这种方式是可行的,那么什么时候可以将(纯)虚函数为private了?这些都是本文将要讨论的主题。一起来看看。
  • 在基类中定义了public虚函数,在派生类中将其重写,但是设置为private什么通过基类指针仍然可以发生动态绑定调用派生类中的private虚函数? 例子如下: class Base { public: // public虚函数 virtual void ...
  • 同上利用虚函数private外部访问成为可能!.。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  • 纯虚函数为private吗?

    千次阅读 2012-11-24 10:51:38
    我们把一个仅仅含有纯虚函数的类称为接口...那么,让我们想一想,纯虚函数或者虚函数可以为private吗?如果这种方式是可行的,那么什么时候可以将(纯)虚函数为private了?这些都是本文将要讨论的主题。一起来看看。
  • 虚函数private

    2013-09-04 02:05:37
    我们把一个仅仅含有纯虚函数的类称为...那么,让我们想一想,纯虚函数或者虚函数可以为private吗?如果这种方式是可行的,那么什么时候可以将(纯)虚函数为private了?这些都是本文将要讨论的主题。一起来看看。 一
  • C++ 虚函数详解

    千次阅读 多人点赞 2021-12-27 20:43:38
    这里写目录标题概述类的虚表一般继承(无虚函数覆盖)一般继承(有虚函数覆盖)多重继承(无虚函数覆盖)多重继承(有虚函数覆盖)虚表指针动态绑定 概述 C++中的虚函数的作用主要是实现了多态的机制。关于多态,...
  • 虚函数指针 虚函数

    千次阅读 2020-02-04 14:02:42
    只有用virtual声明类的成员函数,称之为虚函数。 2.虚函数的作用 就是一句话:实现多态的基石 实现多态的三大步: 1.存在继承关系 子类继承父类 2.子类重写父类的virtual function 3.子类以父类的指针或者是引用的...
  • C++、类继承与虚函数

    千次阅读 2022-04-11 10:07:50
    类继承与虚函数的一些基本概念。
  • 子类可以继承父类的私有虚函数-因为只是方法不是变量 子类 class WeatherBase { private: virtual void init(); } class Rain : public WeatherBase { private: virtual void init(); } 一个成员函数被定义...
  • 我们知道一般函数在编译时就静态地编译到了执行文件中,其相对地址在程序运行期间是不发生变化的,而虚函数在编译期间是不被静态编译的,它的相对地址是不确定的,它会根据运行时期对象实例来动态判断要调用的函数,...
  • 用effective C++中的话说就是private继承是实现继承。...这时可以private继承。或者Base和Derivative根本没有任何逻辑上的联系,单纯的D想要复用一下B的代码,这时就用private 继承。 在一个对象的内存空间中有
  • 纯虚函数为private

    千次阅读 2013-11-19 08:28:01
    我们把一个仅仅含有纯虚函数的类称为接口...那么,让我们想一想,纯虚函数或者虚函数可以为private吗?如果这种方式是可行的, 那么什么时候可以将(纯)虚函数为private了?这些都是本文将要讨论的主题。一起来看看
  • 虚函数详解

    万次阅读 多人点赞 2019-03-09 20:05:26
    文章目录一、虚函数实例二、虚函数的实现(内存布局)1、无继承情况2、单继承情况(无虚函数覆盖)3、单继承情况(有虚函数覆盖)4、多重继承...问题1、构造函数什么不能定义为虚函数2、析构函数什么要定义为虚函数...
  • 本博客主要通过查看类的内容的变化,深入探讨有关指针和表的问题。 一、继承产生的基类表指针和基类表 ...private: int c; }; class Son1 :virtual public Base { public: int a; protected: i
  • C 中的虚函数(virtual function)

    千次阅读 2021-05-23 09:37:39
    简介虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。假设我们有下面的类层次:class Father{public:virtual void foo() { cout << "Father::foo() is called"<...
  • C++虚函数详解

    千次阅读 多人点赞 2021-05-26 10:25:43
    1.虚函数的使用? 1.1虚函数的定义 在实现c++多态时会用到虚函数虚函数使用的其核心目的是通过基类访问派生类定义的函数。...上述代码在基类中定义了一个test的虚函数,所有可以在其子类重新定义父
  • 下面的代码编译结果报错。 test.c: In function `int main(int, char**)': test.c:18:22: error: `virtual void TEST2::testxiongyf()' is private test.c:60:25: error: within this ...如果把private切换public,
  • 友元函数&虚函数

    千次阅读 2018-03-21 09:34:50
    被友元的虚函数,是可以被继承的三个类Myclass,Myclass2,son,Myclass对Myclass2的set函数友元,son继承Myclass2,如果son不重写set函数,而是直接继承Myclass2的set,是可以操作Myclass私有属性的。#include &...
  • C++ 多态与虚函数

    千次阅读 2022-03-24 17:15:50
    多态性与虚函数多态性虚函数 多态性 多态性是面向对象程序设计的关键技术之一,若程序设计语言不支持多态性,不能称为面向对象的语言,利用多态性技术,可以调用同一个函数名的函数,实现完全不同的功能 在C++中有两...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 85,570
精华内容 34,228
关键字:

虚函数可以为private

友情链接: shumaxianshi.rar