精华内容
下载资源
问答
  • 2018-02-22 15:56:40

    虚函数继承和虚继承是完全不同的两个概念。

    虚函数继承是解决多态性的,当用基类指针指向派生类对象的时候,基类指针调用虚函数的时候会自动调用派生类的虚函数,这就是多态性,也叫动态编联。

    虚继承就是为了节约内存,他是多重继承中的特有的概念。适用于菱形继承形式。

    比如B继承于A、C继承于A、D继承于B和C,显然D会继承两次A(图1)。因此,为了节省空间,可以将B、C对A的继承定义为虚拟继承,而A就成了虚拟基类(图2)。代码如下:

     A    A           A
      \    /           / \
      B   C           B  C
       \  /            \  /
       D             D
      (图1)          (图2)

    class A; 
    class B:vitual public A; 
    class C:vitual public A; 
    class D:public B,public C; 

    虚继承的时候子类会有一个指向自己虚函数表的指针,同时也会加入一个指向父类的虚类指针,然后还要包含父类的所有内容。

    虚继承时如果子类父类都有虚函数,那么它会重新建立一张虚表,不包含父类虚表的内容;而在普通的继承中却是在父类虚表的基础上建立一张虚表。这就意味着如果虚继承中子类父类都有各自的虚函数,在子类里面就会有两个虚函数表指针,一个指向父类的虚表,一个指向子类的虚表,而普通的继承只有一个指向子类虚表的指针。代码说明:

    class A
    {
        int k;
    public:
        virtual void aa(){};
    };
    
    class B:public virtual A
    {
        int j;
    public:
        virtual void bb(){};
    };
    
    class C:public virtual B
    {
        int i;
    public:
        virtual void cc(){};
    };
    
    int main()
    {
        cout << sizeof(A) << endl;
        cout << sizeof(B) << endl;
        cout << sizeof(C) << endl;
        system("pause");
        return 0;
    }

    输出结果为:8、20、32。

    怎么来的呢?类A中包含一个整型变量k(4字节),一个虚表指针(4字节),所以一共8字节。类B中,一个整型变量j(4字节),一个虚表指针(4字节),因为B虚继承于A,所有会有一个指向类A的虚类指针(4字节),同时还要包含类A中的整型变量k(4字节)以及类A的虚表指针(4字节),所以一共20字节。类C同理。

    如果将上述代码改为普通继承,那么输出结果为:8、12、16。没有虚类指针,也不会有多个虚表指针。

    更多相关内容
  • JavaScript构造函数继承

    千次阅读 2022-01-26 01:24:51
    首先介绍对象的call()函数和apply()函数,这两个函数的作用相同、用法不同。它们的作用均是指定当前调用函数的this对象是谁。 call()函数:在第一个传递的参数为一个对象,该对象为该函数的this对象,后面依次传递...

            首先介绍对象的call()函数和apply()函数,这两个函数的作用相同、用法不同。它们的作用均是指定当前调用函数的this对象是谁。

            call()函数:在第一个传递的参数为一个对象,该对象为该函数的this对象,后面依次传递函数的实参。

            apply()函数:与call函数大致相同,不同的是实参是以数组的形式传递,用一个数组存储所有实参并作为第二个参数传入apply()函数中。

            而构造函数的原理就是利用call函数,在子类的构造函数中用call函数调用父类的构造函数,即父类构造函数.call(this,参数1,参数2...);子类的每个实例对象就将父类的所有属性、方法复制了一份。

            var p1 = function(name) {
                this.name = name;
                this.p = function() {
                    console.log('qwefdew');
                }
            }
            var p2 = function(name, age) {
                p1.call(this, name);
                this.age = age;
            }
            p2.prototype.sayname = function() {
                console.log(this.name);
            }
            var p3 = new p2('ppg', 18);
            p3.sayname();
            p3.p();

                                                                

     构造函数继承缺点:

            该方法只能继承父类的方法与属性,不能继承其原型的属性和方法。

            每个子类都复制了一份父类的实例对象的属性,函数空间损耗大。

    展开全文
  • 简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会...

    js原型链继承与构造函数继承的优缺点及解决方案


    1. 原型链的概念

    ECMAScript 中描述了原型链的概念,并将原型链作为实现继承的主要方法。其基本思想是利用原型让一个引用类型继承另一个引用类型的属性和方法。简单回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是所谓原型链的基本概念。
    摘自《JavaScript高级程序设计》原型链继承解释

    简单的来说 原型链就是一种关系
    一种实例对象和原型对象之间的关系,关系是通过原型__proto__ 来联系的

    2. 原型链继承

         // 实现原型链有一种基本模式,其代码大致如下。
         // 第一个构造函数
         function SuperType() {
             this.theShy = 'niubi';   // shy爹牛逼
         }
         //第二个构造函数
         function SubType() {
             this.xiaohu = '2200';  // ps: 一虎之力 奥利给
         }
    
         SuperType.prototype.getAbility = function () {
             return this.theShy
         }
    
         SubType.prototype.shuchu = function () {
             return this.xiaohu
         }
         // SubType的原型继承了 SuperType
         //  这样会重写SubType.prototype中constructor中的值  指向SuperType
         SubType.prototype = new SuperType();  
         // 让构造器的指向更改回正确的指向 
         SubType.prototype.constructor = SubType;
    
         var instance = new SubType();
         console.log(instance);  // 图1-1
         instance.theShy = 'too niubi'
         var instance2 = new SubType();
         console.log(instance2.theShy) // 'too niubi'  
         // 通过原型链继承 所有实例公用一套变量  在一个实例中对变量进行了改变 ,则所有实例中的变量都被改变了
         console.log(instance.getAbility()); // 'niubi'
    

    instance的实例
    图1-1

    原型链继承的优缺点

    优点:能通过instanceOf和isPrototypeOf的检测

    注意:给原型添加方法的语句一定要放在原型替换SubType.prototype = new SuperType();之后

    缺点:(1)SuperType中的属性(不是方法)也变成了SubType的prototype中的公用属性,
    如上面例子中的theshy属性,被instance修改后 instance2.theshy获得的是被修改后的变量
    (2)创建子类型的时候,不能像父类型的构造函数中传递参数。

    2.构造函数继承

    function SuperType(name) {
                this.name = name;
              //  this.colors = ['red', 'yellow', 'blue'];
            }
    
            function SubType(name) {
                //可以向父类中传递参数
                SuperType.call(this, name)
                // console.log(this);  //
            }
    
            var instance1 = new SubType('letme');
            var instance2 = new SubType();
            console.log(instance1.name);  //  'letme'
            console.log(instance2.name);  //  undefined
    
    构造函数继承的优缺点
        // 原理:在子类型构造函数的内部调用超类型构造函数
        // 优点:解决了superType中的私有属性变公有的问题,可以传递参数
        // 缺点:方法在函数中定义,无法得到复用
    

    3.组合继承

    通俗来讲就是用原型链实现对原型属性和方法的继承,用借用构造函数继承来实现对实例属性的继承。

    function SuperType(name) {
                this.name = name;
                this.height = 178;
                this.colors = ["red", "blue", "green"];
            }
            SuperType.prototype.sayName = function () {
                // console.log(this.name);
                return this.name
            }
            SuperType.prototype.modified = function(height){
                this.height = height
                return this.height
            }
            SuperType.prototype.getHeight = function(){
                return this.height
            }
    
            function SubType(name, age) {
                SuperType.call(this, name);
                this.age = age;
            }
            // 原型继承  SubType的实例继承了SuperType的方法
            SubType.prototype = new SuperType();
            // 由于重写了SubType的原型 导致SubType的实例的构造器(constructor)
            // 指向错误 会指向SuperType 将其矫正指回SubType;
        
            SubType.prototype.constructor = SubType;
            SubType.prototype.sayAge = function () {
                alert(this.age);
            };
            
            var instance1 = new SubType('knight', 18);
            var instance2 = new SubType();
            console.log(instance1.modified(180)); //180
            console.log(instance2.getHeight());  // 178
            console.log(instance1.sayName()); // knight
            console.log(instance2.sayName()); // undefined
             
             // 借用了构造函数继承 在每一个实例中都创建了一个新的副本 
             // 在其中一个实例中修改SuperType中的属性值不会影响另一个实例中的属性值
    
    
    

    在这个例子中,SuperType 构造函数定义了两个属性:name 和 colors。SuperType 的原型定义了一个方法 sayName()。SubType 构造函数在调用 SuperType 构造函数时传入了 name 参数,紧接着又定义了它自己的属性 age。然后,将 SuperType 的实例赋值给 SubType 的原型,然后又在该新原型上定义了方法 sayAge()。这样一来,就可以让两个不同的 SubType 实例既分别拥有自己属性——包括 colors 属性,又可以使用相同的方法了。
    组合继承避免了原型链和借用构造函数的缺陷,融合了它们的优点,成为 JavaScript 中最常用的继承模式。而且,instanceof 和 isPrototypeOf()也能够用于识别基于组合继承创建的对象。

    摘自《JavaScript高级程序设计》组合继承解释


    实例对象使用属性或方法的规则

    实例对象使用的属性或方法,现在实例中查找,如果有则使用自身的属性或方法,
    如果没有,则通过__proto__指向的原型对象 查找方法,找到则使用,
    如果找不到则继续向__proto__寻找,直到未找到时报错

    构造函数和原型对象和实例对象之间的关系

    1.构造函数可以实例化对象
    2.构造函数中有一个属性叫prototype,是构造函数的原型对象
    3. 构造函数的原型对象(prototype)中有一个constructor 构造器,这个构造器指向的就是自己所在的原型对象所在的构造函数
    4. 实例对象的原型对象__proto__ 指向的是该构造函数的原型对象(prototype)
    5. 构造函数的原型对象(prototype)中的方法是可以被实例对象直接访问

    展开全文
  • #include using ... C类,虚函数继承,一个整理4B,自己的虚指针4B(指向的虚函数表仅cc一个函数),然后把B类的12B全继承一份,共20B 注意:上面两个继承与虚继承是不一样的,虚继承就记住是菱形继承时用到即可

    #include<bits/stdc++.h>
    using namespace std;
    class A{public:int k;virtual void aa(){};};
    class B:public A{public:int j;virtual void bb(){};};
    class C:public virtual B{public:int i;virtual void cc(){};};
    int main(){cout<<sizeof(A)<<sizeof(B)<<sizeof(C)<< endl;return 0;}
    //8 12 20

     

    A类,一个整型4B,一个虚函数故有一个虚函数指针4B,共8B【A类的虚函数表只有一个虚函数地址】

    B类,普通继承,一个整型4B,继承下来的一个整型4B,虚指针4B,共12B【B类的虚函数表有aa与bb两个虚函数地址】

    C类,虚函数继承,一个整理4B,自己的虚指针4B(指向的虚函数表仅cc一个函数),然后把B类的12B全继承一份,共20B

    注意:上面两个继承与虚继承是不一样的,虚继承就记住是菱形继承时用到即可

    展开全文
  • C++类成员函数继承

    千次阅读 多人点赞 2019-05-20 00:38:23
    如果对于父类函数(virtual/非virtual),如果子类没有同名函数,则正常继承 2 . 对于父类函数(virtual、非virutal),子类有同名函数,无同型函数,则不能调用父类函数 3 . 对于父类函数(virtual、非virtual),...
  • JS继承之构造函数继承

    千次阅读 2018-09-05 16:23:26
    构造函数继承的精华是子类中SuperClass.call(this)语句了 function Shape(id) { this.name = 'shape'; this.id = id; this.toString = function() {return this.name;}; } Shape.prototype.showName = ...
  • 上次博客跟大家分享了自己对原型链继承的理解,想看的同学欢迎猛击这里,上次说到原型链继承有一些问题,主要是两方面的。我们举个栗子来说明下: Q1:共享的超类属性能被任何实例改写,这个是很危险的!看下面一段...
  • C++11:继承构造函数

    千次阅读 2022-03-13 15:33:40
    } 继承构造函数 以上方法虽然可行,但是代码非常繁琐切重复性高,而C++11中的继承构造函数特征正是用于解决派生类隐藏基类同名函数的问题。 可以通过 using Base::SomeFunction来表示使用基类的同名函数。 所以以上...
  • ​ 面向对象中的三大特性:封装,继承,多态,继承就是继承父构造函数的属性和方法。这样的话就可以实现代码的复用,且继承是多态的前提。 开篇说重点: 文中Person为父构造函数,Stundet为子构造函数,我们现在要...
  • C#构造函数继承

    万次阅读 2012-10-14 20:45:05
    //继承的类,子类会调用父类无参的构造函数。从底层开始,一个父类,一个父类的调用. public class MyClass { public MyClass() { Console.WriteLine("MyClass:默认构造函数"); } public MyClass(int a...
  • C++11 继承构造函数

    万次阅读 多人点赞 2018-08-15 14:43:53
    如果基类拥有多个构造函数,那么子类也需要实现多个与基类构造函数对应的构造函数。 class Base { public: Base(int va) :m_value(va), m_c(‘0’){} Base(char c) :m_c(c) , m_value(0){...
  • 浅谈js中函数继承方式

    千次阅读 2019-07-09 15:44:19
    1. ES5 构造函数继承 function Parent() { this.name = 'parent'; this.colors = ['black', 'yellow', 'red'] } function Child() { Parent.call(this); this.type = 'child'; } var q1 = ne...
  • shell中函数继承问题

    万次阅读 2013-04-25 19:54:19
    有些情况下可能需要继承函数,以方便透明使用,方法非常简单,使用“export -f”,注意参数“-f”,它表示函数的意思,不带参数的export只针对变量。 ​ function ifprop(){echo ":$1=$2"}export -f ifprop ...
  • 文章目录1 公有继承时三种类型的函数行为1.1 纯虚函数 (pure virtual)1.2 普通虚函数**1.2.1 方法一****1.2.2 方法二**1.3 非虚函数2 重写 (override)小结 1 公有继承时三种类型的函数行为 公有继承包含两部分:一是...
  • C++、类继承与虚函数

    千次阅读 2022-04-11 10:07:50
    继承与虚函数的一些基本概念。
  • 构造函数继承构造函数继承构造函数继承构造函数继承构造函数继承构造函数继承构造函数继承构造函数继承构造函数继承
  • Java中构造函数可以被继承

    千次阅读 2021-03-11 10:44:08
    Java中构造函数不能被继承。子类在继承父类的时候,首先运行父类构造函数,也就是说,运行子类时会先调用父类的构造函数。构造函数一般用来初始化成员属性和成员方法。Java中构造函数不能被继承。解析:子类在继承...
  • 【C++】纯虚函数、虚函数、普通函数继承

    千次阅读 多人点赞 2018-09-06 09:53:34
    由于纯虚函数的出现,基类变成了一个抽象类,只能被继承,而不能被实例化;纯虚函数的话,必须在派生类中重载。所以纯虚函数只提供一个方法的接口,实现方式需要派生类自己去写。 虚函数:提供接口,并提供默认的...
  • C++继承类的构造函数

    千次阅读 2019-02-28 16:28:45
    C++继承类的构造函数 ** 一.内部赋值的构造函数 二.用父类指针初始化子类对象的构造函数 class student { public: int num; int age; student() //默认构造函数 { num = 10086; age = 18; } //...
  • C++ static函数 继承问题

    万次阅读 2010-12-09 18:43:00
    今天在论坛上看了些关于 C++中static函数 继承的问题,顺便弄个小程序试了试。。 #include <iostream><br /> using namespace std; <br /> class base { public:  static int ...
  • 理解继承(二):构造函数继承

    千次阅读 2017-10-08 11:14:09
    原文:Javascript面向对象编程(二):构造函数继承 对象之间继承的五种方法 例如:现在有一个“动物”的构造函数 function Animal(){ this.species = "动物"; } 还有一个“猫”对象的构造函数 ...
  • Python类继承及super()函数

    万次阅读 多人点赞 2019-06-27 19:57:36
    文章目录Python中单类继承普通类方法继承初始化函数继承Python中多类继承 Python中单类继承 Python是一门面向对象的编程语言,支持类继承。新的类称为子类(Subclass),被继承的类称为父类、基类或者超类。子类继承...
  • 继承中的虚函数与非虚函数

    千次阅读 2018-01-09 18:06:20
    子类继承父类, 包括继承了虚函数和非虚函数 子类调用父类中的非虚函数 Base::PrintWord(), 在这个非虚函数里它又调用了虚函数doPrintWord()。 实验表明调用的虚函数执行的是重写的子类虚函数。 大致的代码可以...
  • 函数、纯虚函数继承时的问题

    千次阅读 2019-01-21 11:07:08
    如果子类需要实例化,就必须实现纯虚函数(有纯虚函数的类不能被实例化,子类继承了有纯虚函数的父类,则子类也就有了纯虚函数,如果此时,不实现子类的纯虚函数,也就不用实例化了)。 父类中的虚函数和普通函数...
  • C++继承和多态(虚函数、纯虚函数、虚继承

    千次阅读 多人点赞 2019-03-05 11:32:40
    C++继承和多态(虚函数、纯虚函数、虚继承) 一:继承 继承的概念:为了代码的复用,保留基类的原始结构,并添加派生类的新成员。 继承的本质:代码复用 我们用下图解释下: 那么我们这里就可以提出几...
  • 5.继承体系同名函数的关系   1.单继承与多继承  1.1单继承:  一个子类只有一个直接父类。   class Person class Student : public Person class Monitor : public Student  1.2多继...
  • C++继承下的构造函数

    千次阅读 2019-04-17 16:50:35
    当我们创建一个派生类对象的时候,基类构造函数将会被自动调用,用于初始化派生类从基类继承过来的成员变量,而派生类中新增的成员则需要从新定义构造函数用于初始化了。 #include<iostream> using namespace ...
  • c++之哪些成员函数不能被继承

    千次阅读 2020-06-14 21:25:50
    C++中,并不是所有的成员函数都能被子类继承,有三类成员函数不能被子类继承,分别是:构造函数(包括拷贝构造)、析构函数、赋值运算符重载函数。 一,构造函数  构造方法用来初始化类的对象,与父类的其它成员...
  • 构造函数和析构函数能否被继承

    千次阅读 2018-07-24 11:28:56
    构造函数不能被继承 参考:https://blog.csdn.net/maosong00/article/details/12012895 构造方法是用来初始化类的对象,与父类的其他成员不同,他不能被子类继承(子类可以继承父类所有的成员变量和成员方法,但是...
  • C++继承关于析构函数的问题

    千次阅读 2018-06-29 09:50:30
    在c++继承中,也知道要把父类的析构函数用virtual修饰 关于析构函数的基本使用方法,也是很简单。 但是!最近在工作中,遇到了一个关于析构函数很奇葩的问题!导致查了半天的Bug,才发现是少声明了一个析构函数。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,182,751
精华内容 473,100
关键字:

函数继承

友情链接: design.rar