前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C++ Virtual And Pure Virtual Explained

C++ Virtual And Pure Virtual Explained

作者头像
吕海峰
发布2018-04-03 15:39:11
9140
发布2018-04-03 15:39:11
举报
文章被收录于专栏:BrianBrian

Virtual

Virtual Function是成员函数,其行为在派生类中被覆盖。与非虚函数不同的是,即使没有关于类的实际类型的编译时信息,也会保留重写的行为。如果派生类使用指针或者对基类的引用进行处理,则对被覆盖的虚函数的调用将调用派生类中定义的行为。

代码语言:javascript
复制
#include <iostream>

struct Base {
    virtual void f() {
        std::cout << "base\n";
    }
};
struct Derived : Base {
    void f() override { // 'override' is optional
        std::cout << "derived\n";
    }
};
int main()
{
    Base b;
    Derived d;
    
    // virtual function call through reference
    Base& br = b; // the type of br is Base&
    Base& dr = d; // the type of dr is Base& as  well
    br.f(); // prints "base"
    dr.f(); // prints "derived"
    
    // virtual function call through pointer
    Base* bp = &b; // the type of bp is Base*
    Base* dp = &d; // the type of dp is Base* as  well
    bp->f(); // prints "base"
    dp->f(); // prints "derived"
    
    // non-virtual function call
    br.Base::f(); // prints "base"
    dr.Base::f(); // prints "base"
}
//输出
base
derived
base
derived
base
base

虚函数使其类成为多态基类,派生类可以覆盖虚函数。 通过基类指针/引用调用的虚函数将在运行时解析。 也就是说,使用对象的动态类型而不是静态类型。静态类型是指不需要考虑表达式的执行期语义,仅分析程序文本而决定的表达式类型。静态类型仅依赖于包含表达式的程序文本的形式,而在程序运行时不会改变。动态类型是由一个左值表达式表示的左值所引用的最终派生对象的类型。 大致可以这么理解:

  • 静态类型:对象在声明时采用的类型,在编译期既已确定。
  • 动态类型:通常是指一个指针或引用目前所指对象的类型,是在运行期决定的。
  • 静态绑定:绑定的是静态类型,所对应的函数或属性依赖于对象的静态类型,发生在编译期。
  • 动态绑定:绑定的是动态类型,所对应的函数或属性依赖于对象的动态类型,发生在运行期。

Pure Virtual

抽象类是定义或继承至少一个最终覆盖纯虚函数的类,一个纯虚函数隐含的使其自己的类被定义为抽象类,抽象类不能被实例化,只能通过派生类来覆盖实现所有继承的纯虚函数,如果派生类不覆盖实现所有的纯虚函数,那么程序编译不通过报错。何为纯虚函数?格式如下: declarator virt-specifier(optional) = 0 eg: virtual func(optional) = 0; =0只能出现在声明标识符之后或者可选标识符(virtual、final)之后,不能出现在成员函数定义中。

代码语言:javascript
复制
#include <iostream>

struct Base {
    virtual int g();
    virtual ~Base() {}
};

struct A : Base {
    // ok, declares three member virtual functions, two of them pure
    virtual int f() = 0;
	//override代表派生类覆盖父类g()方法
    virtual int g() override = 0;
    virtual int h();
    
    // ok, destructor can be pure too
    virtual ~A() = 0;
    
    // error: pure-specifier on a function definition
    virtual int b()=0 {}
};
//输出为
 virtual int b()=0 {} error: initializer on function does not look like a pure-specifier
代码语言:javascript
复制
struct Abstract {
    virtual void f() = 0; // pure virtual
    virtual void g() {}; // non-pure virtual
    ~Abstract() {
        g(); // okay, calls Abstract::g()
        // f(); // undefined behavior!
        Abstract::f(); // okay, non-virtual call
    }
};
 
//definition of the pure virtual function
void Abstract::f() { std::cout << "A::f()\n"; }
 
struct Concrete : Abstract {
    void f() override {
        Abstract::f(); // OK: calls pure virtual function
    }
    void g() override {}
    ~Concrete() {
        g(); // okay, calls Concrete::g()
        f(); // okay, calls Concrete::f()
    }
};
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-07-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Virtual
  • Pure Virtual
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档