精华内容
下载资源
问答
  • 在C++中,基类必须指出希望派生类重定义哪些函数,定义为virtual的函数是基类期望派生类重新定义的,基类期望派生类继承的函数不能定义为虚函数。 class Base { public: virtual void display(){ cout ;} }...

    在C++中,基类必须指出希望派生类重定义哪些函数,定义为virtual的函数是基类期望派生类重新定义的,基类期望派生类继承的函数不能定义为虚函数。


    class Base
    {
    public:
        virtual void display(){ cout << "base::display" << endl;}
    
    };
    
    class Derived : public Base
    {
        
    };
    
    
    int main(int argc, char *argv[])
    {
        Derived d;
        d.display();
        return EXIT_SUCCESS;
    }

    输出:base::display


    内存结构:


    程序正常运行,为什么不能定义为虚函数呢,效率问题?


    展开全文
  • C++ 哪些不能为虚函数

    2019-10-21 19:38:03
    什么是虚函数 ...虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具...

    什么是虚函数

    • 定义:

    虚函数必须是基类的非静态成员函数,其访问权限可以是protected或public,在基类的类定义中定义虚函数的一般形式:
      virtual 函数返回值类型 虚函数名(形参表){ 函数体 }

    • 作用:

    虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚函数具有相同的形参个数和形参类型,以实现统一的接口,不同定义过程。如果在派生类中没有对虚函数重新定义,则它继承其基类的虚函数。

    当程序发现虚函数名前的关键字virtual后,会自动将其作为动态联编处理,即在程序运行时动态地选择合适的成员函数。

    • 使用方法:

    动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式:
    指向基类的指针变量名->虚函数名(实参表)或 基类对象的引用名. 虚函数名(实参表)

    • 其它说明:

    虚函数是C++多态的一种表现:

    例如:子类继承了父类的一个函数(方法),而我们把父类的指针指向子类,则必须把父类的该函数(方法)设为virtual(虚函数)。使用虚函数,我们可以灵活的进行动态绑定,当然是以一定的开销为代价。 如果父类的函数(方法)根本没有必要或者无法实现,完全要依赖子类去实现的话,可以把此函数(方法)设为virtual 函数名=0 我们把这样的函数(方法)称为纯虚函数。如果一个类包含了纯虚函数,称此类为抽象类 。

    什么样的函数不能声明为虚函数?

    1)不能被继承的函数。2)不能被重写的函数。

    • 普通函数

    普通函数不属于成员函数,是不能被继承的。普通函数只能被重载,不能被重写,因此声明为虚函数没有意义。因为编译器会在编译时绑定函数。

    而多态体现在运行时绑定。通常通过基类指针指向子类对象实现多态。

    • 友元函数

    友元函数不属于类的成员函数,不能被继承。对于没有继承特性的函数没有虚函数的说法。

    • 构造函数

    首先说下什么是构造函数,构造函数是用来初始化对象的。假如子类可以继承基类构造函数,那么子类对象的构造将使用基类的构造函数,而基类构造函数并不知道子类的有什么成员,显然是不符合语义的。从另外一个角度来讲,多态是通过基类指针指向子类对象来实现多态的,在对象构造之前并没有对象产生,因此无法使用多态特性,这是矛盾的。因此构造函数不允许继承。

    • 内联成员函数

    我们需要知道内联函数就是为了在代码中直接展开,减少函数调用花费的代价。也就是说内联函数是在编译时展开的。而虚函数是为了实现多态,是在运行时绑定的。因此显然内联函数和多态的特性相违背。

    • 静态成员函数

    首先静态成员函数理论是可继承的。但是静态成员函数是编译时确定的,无法动态绑定,不支持多态,因此不能被重写,也就不能被声明为虚函数。

    展开全文
  • C++类中的虚函数不能为模板函数 首先,理解模板的原理。例如,定义了一个模板函数: template<typename A> void Func(const A& a) { std::cout <<"Func(const A& a) : "<< a <<...

     

    C++类中的虚函数不能为模板函数

    首先,理解模板的原理。例如,定义了一个模板函数:

    template<typename A>
    void Func(const A& a) {
        std::cout <<"Func(const A& a) : "<< a << std::endl;
    }

    编译器在编译期间,会检查代码中哪些地方使用了这个函数,例如,如果在整个程序中使用到了两种类型:Func<int>(9);

    Func<float>(9.3); 则编译器会生成两份函数的二进制代码:void Func(const int& a),以及void Func(const float& a)。

     

    由于对于类的虚函数来说,其是否被调用是在程序运行的时候才知道,因此编译阶段不知道需要生成几份函数。    例如,基类是Base,有两个子类A和B, 代码中使用基类的指针来调用子类的虚函数 ,在编译阶段并不能知道调用的是哪个子类的虚函数,因此,编译器不知道类A和B中的模板函数被调用的情况,因此,不知道需要生成几份函数。

    另外,每个含有虚函数的类中都有一个虚函数表,该虚函数表存储着该类的所有的虚函数的地址,因此,虚函数为模板函数时,该表的大小是不知道的,因此编译器禁止!

    但是,类的普通的成员函数是可以为模板函数的!


    From C++ Templates The Complete Guide:

    Member function templates cannot be declared virtual.  This constraint is imposed because the usual implementation of the virtual function call mechanism uses a fixed-size table(虚函数表必须是fixed sized,我的盲点) with one entry per virtual function.     However, the number of instantiations of a member function template is not fixed until the entire program has been translated. Hence, supporting virtual member function templates would require support for a whole new kind of mechanism in C++ compilers and linkers. In contrast, the ordinary members of class templates can be virtual because their number is fixed when a class is instantiated.

     

    Book:

    http://www.tmplbook.com/

     

    Test:

    #pragma once
    #include <iostream>
    class templateFunc
    {
    public:
    	void fun() {
    
    	}
    
    	//ok:
    	template<typename A>
    	void testFunc(const A& a) {
    		std::cout << "templateFunc::testFunc(const A& a) : " << a << std::endl;
    	}
    
    	//error: 编译器会直接报错
    	/*template<typename A>
    	virtual void testMe(const A& a) {
    
    	}*/
    };
    
    template<typename A>
    void Func(const A& a) {
    	std::cout <<"Func(const A& a) : "<< a << std::endl;
    }
    
    int main() {
    	templateFunc obj;
    	obj.testFunc<int>(6);
    
    	Func<int>(9);
    	return 0;
    }
    
    

     

     可以结合模板函数与虚函数多态的机制

    stack overflow上有人提到:

    However, there are a few powerful and interesting techniques stemming from combining polymorphism and templates, notably so-called type erasure.

    C++中的类型擦除(type erasure in c++)

    https://blog.csdn.net/qq_35865125/article/details/109235025

     

    Ref:

    https://blog.csdn.net/creambean/article/details/90085246

    https://stackoverflow.com/questions/2354210/can-a-class-member-function-template-be-virtual#

     

    展开全文
  • 文章目录05C++默认编写哪些函数什么情况下自动生成的=不能用?06不想用自动生成的函数07多态基类声明析构函数 05C++默认编写哪些函数 默认构造函数,拷贝构造函数,拷贝赋值运算符,析构函数 什么情况下自动生成...

    05C++默认编写哪些函数

    默认构造函数,拷贝构造函数,拷贝赋值运算符,析构函数

    什么情况下自动生成的=不能用?

    =失效
    =失效
    无法生成=
    不能用
    成员是引用
    成员是const
    基类的=是private

    06不想用自动生成的函数

    前提知识:

    1. 编译器产生的函数都是public的
    2. 基类的函数是private则,派生类就不能生成

    方式1:把自动生成的函数声明为private,不实现
    方式2:专门定义一个基类,不想用的函数在基类定义为private,在继承基类即可,class son:private father{…}

    07为多态基类声明虚析构函数

    问题引出

    factory函数
    delete 基类指针
    基类-非虚析构函数
    有多个派生类
    return基类指针指向派生类对象
    派生类部分没有被销毁-派生类的析构没有调用

    解决方法一:

    factory函数
    delete 基类指针
    基类-virtual析构函数
    有多个派生类
    return基类指针指向派生类对象
    派生类的析构被调用

    解决方法二:
    纯虚函数法

    //定义一个基类
    class A{
    public:
        virtual ~A()=0;//声明,纯虚函数
    }
    A::~A(){}//定义,给派生类用,所以要定义
    
    之后
    派生类析构
    各个基类依次析构

    总结:通过基类接口处理派生类对象,仅限有多态性质的基类

    展开全文
  • 虚函数的定义虚函数的实现机制哪些函数不能被设置为虚函数?虚函数的访问指针访问引用访问对象访问成员函数中的访问构造函数和析构函数中访问纯虚函数抽象类虚析构函数重载、隐藏、覆盖虚拟继承虚拟继承时派生类对象...
  • C++ 类与虚函数知识

    2019-09-23 19:17:55
    空类缺省有哪些成员函数 构造函数 ...静态成员函数不能定义为虚函数 因为静态成员函数没有this指针,并且静态成员函数可以通过类名来访问。 又因为虚函数是放在对象的虚表里面的,同一个类中的所有对...
  • 继承、虚函数注意点

    2016-09-07 20:45:00
    哪些函数不能为虚函数:(定义虚函数一般是为了使用多态性质) 普通函数(非成员函数):不属于类的成员,不能用于多态,只能被重载。 静态成员函数:静态成员函数属于类的信息,被所有对象共享,不归某个对象...
  • 多态公有继承(虚函数)

    千次阅读 2010-08-22 11:24:00
    关键字virtual,定义虚方法.只用于函数原型,不能用于函数定义中。在基类中被声明虚拟的后,他在派生类中将自动成为虚方法。不过,在派生类声明中使用关键字virtual来明确指出哪些函数虚函数也不失一个好办法。
  • 目录树 1.继承 1.1 基类成员在派生类中的访问属性 ...2.4哪些函数不能定义为虚函数 2.5虚函数表指针(vptr)和虚基类表指针(bptr) 2.5.1 虚函数表指针vptr 2.5.2含静态变量、虚函数的类的空间计算 ...
  • virtual析构函数的作用

    2016-06-15 18:12:00
    C++ Primter中讲“在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数”。 析构函数是为了在对象不被使用之后释放它...
  • c++面试题1

    2018-07-30 15:02:56
    二、哪些函数不能声明成虚函数 1. 非成员函数 2. 构造函数 3. 静态成员函数 4. 内联成员函数 5. 友元函数 三、什么析构函数和构造函数内不能调用虚函数 四、什么析构函数最好声明成虚函数 五、...
  • 在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 注意:继承层次的根类一般都要定义虚析构函数.保留字virtual 的...
  • 在C++中,基类必须指出希望派生类重定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 通过动态绑定我们能够编写程序使用继承层次中任意类型的对象,无须...
  • 1、在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 2、要触发动态绑定,满足两个条件:第一,必须指定为虚函数...
  • C++ 面向对象编程笔记

    2019-07-11 21:56:09
    1.在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 2.在 C++ 中,通过基类的引用(或指针)调用虚函数时,发生...
  • 1、在C++中,基类必须指出希望派出类重定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 2、在C++中,通过基类的引用(或指针)调用虚函数时,发生...
  • virtual 语法规则

    2014-04-04 13:57:09
    在C++中,基类必须指出希望派生类重写哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 在C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。引用...
  • 面向对象编程基于三个基本概念:数据...在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。  在 C++ 中,通过基类
  • 在C++中,通过基类的引用(或指针)

    千次阅读 2014-04-01 13:09:35
    在C++中,基类必须指出希望派生类重写哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。  在C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。...
  • 在C++中

    2014-04-01 17:24:27
    在C++中,基类必须指出希望派生类重写哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。  在C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。...
  • 在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。在 C++ 中,通过基类的引用(或指针)调用虚函数时,发生动态绑定...
  • 面向对象编程:   面向对象编程基于三个基本概念:数据抽象、继承和动态绑定。 继承和动态绑定在两个方面简化了...的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。 注意: 在 C++
  • 面向对象编程概述

    2017-03-29 20:21:46
    1、面向对象编程的关键思想是多态性(polymorphism。...在 C++ 中,基类必须指出希望派生类重写哪些函数,定义为 virtual 的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数
  • 目录C++1、C++多态性与虚函数表①C++多态的实现②虚函数的作用③什么析构函数需要定义虚函数什么构造函数不能虚函数?⑤析构函数能抛出异常吗?⑥不能在构造、析构函数中调用虚函数2、智能指针①auto_ptr...
  • C/C++面试题目总结

    千次阅读 2016-06-27 12:07:37
    目录 1. 多态性都有哪些?...4. C++中哪些不能虚函数? 4 5. 类型转换有哪些? (参考) 4 6. 什么要用static_cast转换而不用c语言中的转换? 4 7. 操作符重载(+操作符),具体如何去定义
  • 1 OOP概述 ...在C++中,基类必须指定希望派生类重定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,需要在派生类中继承的不能定义为虚函数。  派生类重新定义的虚函数前面可以加virtual
  • 文章目录一、面向对象的基本概念1、面试题--->面向对象的基本原则?2、面试题--->...析构函数为什么要定义为虚函数?3、面试题--->为什么构造函数不能是虚函数?4、面试题--->是否可以把每个函...

空空如也

空空如也

1 2 3 4
收藏数 70
精华内容 28
关键字:

哪些函数不能定义为虚函数