C++基础#7:继承-单继承,多继承,虚基类

OpenCV安装配置教程VS2022(超级顺利) 博主最开始没打算写这篇博客,只是想简单的在网上找一下最新版的OpenCV的安装配置教程,适用于VS2022的,但是我搜了一早上,也没搜到一个能让我成功安装配置的,看了很多很多文章,根本就没有几篇有用的。所以没办法了,只能自己研究了,于是就整理了这篇博客,希望能帮到和我一样的人,这就是博主一直信奉的利他精神! 阅读详情

1. 前言:

面向对象的三大特性:封装,继承,多态。

类的数据成员和成员函数的定义,很好的诠释了封装这个概念。

本节将介绍面向对象的另一个特性:继承。


2. 继承(inheritance)和派生(derived)的基本概念:

     (1).  类提供了说明一组对象结构的机制。借助于继承这一重要机制,已存在的类具有建立子类的能力,进而建立类的层次,扩充类的定义。
  (2).  继承提供了创建新类的一种方法,一个新类可以通过对已有类进行修改和扩充来定义。从一个类继承定义的新类,将继承已有类的方法和属性,并且可添加不包含在父类中的新方法和属性。新类被称为已有类的子类,又称为派生类,已有类称为新类的父类,又称为基类。(在java中,只有父类,子类之称,没有基类,派生类这样的说法).
     (3).   派生类的三种继承方式:
          第一种,公有继承(public):
                 公有继承的特点是基类的公有成员和保护成员作为派生类的成员时,它们都保持原有的状态,而基类的私有成员仍然是私有的。
         第二种,私有继承(private)
                 私有继承的特点是基类的公有成员和保护成员作为派生类的私有成员,并且不能被这个派生类的子类访问。
        第三种,保护继承(protected)
                保护继承的特点是基类的所有公有成员和保护成员都成为派生类的保护成员,并且只能被它的派生类成员函数或友元访问,基类的私有成员仍然是私有的。


3. 派生与构造函数、析构函数
    (1).  构造函数和析构函数不能够被继承(why?); 
    (2).派生类构造函数的调用顺序:
       a. 调用基类的构造函数,调用顺序按照它们继承时说明的顺序。
       b. 调用子对象类的构造函数,调用顺序按照它们在类中说明的顺序。
       c. 派生类构造函数体中的内容。
    (3).派生类析构函数的调用顺序:  
         和构造函数的顺序完全相反.
    (4). 派生类构造函数使用中应注意的问题:
      a.  派生类构造函数的定义中可以省略对基类构造函数的调用,其条件是在基类中必须有默认的构造函数或者根本没有定义构造函数.
      b.  当基类的构造函数使用一个或多个参数时,则派生类必须定义构造函数,提供将参数传递给基类构造函数的途径.


4. 多继承:
    可以为一个派生类指定多个基类,这样的继承结构称为多继承。多继承可以看作是单继承的扩展。
     (在java中,不允许进行多继承,类似多继承的功能是通过接口(interface)实现的。

 

例子程序1:单继承与多继承的例子:

/* file: inheritanceTest.cpp   */

/* IDE环境: Dev-C++ 4.9.9.2 */
/*例子程序1:单继承与多继承的例子*/


/*本例中类的继承关系如下:     

 *                                                       

 *         public                                       
 *  A <--------- B                      
 *                                                 
 *        private       public                      
 *  A <--------- C <--------- D    
 *                                          
 ***********************/

#include <stdio.h>
  
class  A
{
public:
    A()
    {
        printf("A::constructing ! /n");
        init();
    }
    ~A()
    {
        printf("A::destructing  ! /n");
    }
    void init()       { i = j= k = 0;}
   
    int get_i(void)  { return i; }
    int get_j(void)  { return j; }
    int get_k(void)   { return k; }
   
public: int i;
private: int j;        //private成员不能被派生类直接访问
protected :  int  k;
};

class  B : public A
{
public:
    B()
    {
        printf("B::constructing ! /n");
        init(); // 调用本类的init()函数。
    }  
    ~B()
    {
        printf("B::destructing  ! /n");
    }
    void init(void)  // 方法覆盖,也称方法重写,注意与重载是不同的。
    {
        A::init();     //调用父类的init()函数,这里必须显式地用A::init(), "A::"不能省略
        h = 0;
    } 
 
    void set_h(int x) { h = x; }
    int get_h(void)   { return h; }
   
    void display(void)
    {
         { printf(" B::disp_i i = %d /n", get_i()); }
         { printf(" B::disp_j j = %d /n", get_j()); }
         { printf(" B::disp_k k = %d /n", get_k()); }
         { printf(" B::disp_h h = %d /n", get_h()); }
        
    }
   
    void print(void)
    {
         printf(" B::print i = %d /n", i );
       //  printf(" B::print j = %d /n", j );  //compiler error: 103 F:/devcpptest/devcpptest/derivedTest.cpp `int A::j' is private
         printf(" B::print k = %d /n", k );
         printf(" B::print h = %d /n", h );
    }

private:
    int h;
};

class C: private A
{
public:
      C()
      {
          printf("C::constructing ! /n");
      }
      ~C()
      {
        printf("C::destructing  ! /n");
      }
      void Cprint_i(void)
      {
           printf(" C::Cprint_i i = %d /n", i ); //OK
      }
      //A::j; //compile error:  F:/devcpptest/devcpptest/derivedTest.cpp `int A::j' is private
      A::k;  //调整对A::k的访问控制, 使得 k 可以被C的派生类访问。
};

class D: public C
{
public:
      D()
      {
          printf("D::constructing ! /n");
      }
      ~D()
      {
        printf("D::destructing  ! /n");
      }
     void Dprint_i(void)
     {
       //printf(" D::Dprint_i i = %d /n", i ); //compile error:  F:/devcpptest/devcpptest/derivedTest.cpp `int A::i' is inaccessible
                                            // 对于类C, i是它的私有数据成员(因为C是从父类A以private的方式继承的), 因此,不能被
                                            //它的派生类D访问。
       printf(" D::Dprint_i i = %d /n",  k); //OK
     }
};

void TestFunc(void)
{
    B b;  // 构造函数调用顺序:A ---> B
    b.display();
    b.print();
   
    C c; // 构造函数调用顺序:A ---> C
    //int x = c.get_i(); //compile error: F:/devcpptest/devcpptest/derivedTest.cpp `int A::get_i()' is inaccessible
                        //因为C是以private的方式继承自A的,A的所有public,proteced成员函数都不能被C访问。
                       
    D d; // 构造函数调用顺序:A ---> C ---> D
    d.Dprint_i();
}

int main(void)
{

    TestFunc(); //调用完此函数后,所有在 TestFunc()中定义的变量都将销毁,对于对象来说,在此函数执行完成后,系统自动调用析构函数,
                //而调用的顺序正好与构造函数的调用顺序相反。
    while(1);
    return 0;
}

例子程序1代码说明:

compile error:  F:/devcpptest/devcpptest/derivedTest.cpp `int A::i' is inaccessible
编译错误,因为对于类C, i是它的私有数据成员(因为C是从父类A以private的方式继承的), 因此,不能被它的派生类D访问。


compile error: F:/devcpptest/devcpptest/derivedTest.cpp `int A::get_i()' is inaccessible
编译错误,因为C是以private的方式继承自A的,A的所有public,proteced成员函数都不能被C访问。

 

5. 同一基类多次拷贝引起的二义性:
    在多基派生中,如果在多条继承路径上有一个公共的基类,则在这些路径的汇合点,便会产生来自不同路径的公共基类的多个拷贝,这样,
    便会引起二义性,具体地,有下面两种情况:

同名成员的二义性,和同一基类被多次继承产生的二义性(用虚函数来解决)。

具体说明如下:
    (1)例子程序2:同名成员的二义性举例:

    /* IDE环境: Dev-C++ 4.9.9.2 */
    /* file: derivedTest2.cpp */
    /*例子程序2:同名成员的二义性举例*/


    #include <stdio.h>
   
    class A
    {
    public:
    int a()
    {
     return 1;
          }
    };
    class B :public A
    {
       public:
          float a()
            {
                return float(1.2345);
          }
    };
    class C : public A
    {
    };
    class D : public B, public C
    {
    };
    int main()
    {
        D d;
        printf(" %f ",d.a()); //compiler error: F:/devcpptest/devcpptest/derivedTest2.cpp request for member `a' is ambiguous;
                              // F:/devcpptest/devcpptest/derivedTest2.cpp: candidates are: int A::a() float B::a()
                              // d.a() 不知道是要调用int a()还是float a(), 
        while(1);
    }
   

例子程序2代码说明:

compiler error: F:/devcpptest/devcpptest/derivedTest2.cpp request for member `a' is ambiguous;
F:/devcpptest/devcpptest/derivedTest2.cpp: candidates are: int A::a() float B::a()
编译错误,d.a() 不知道是要调用int a()还是float a(),a是同名函数。这就产生了“同名成员的二义性”问题。


    (2). 例子程序3:同一基类被多次继承产生的二义性(用虚函数来解决) :
   

    /* IDE环境: Dev-C++ 4.9.9.2 */
    /* file: derivedTest3.cpp */
    /*例子程序3:同一基类被多次继承产生的二义性(用虚函数来解决)*/
   
    #include <stdio.h>
         
    class  B 
    { public : int  b ;} ;
    class  B1 : public  B
    { private : int  b1 ; } ;
    class  B2 : public  B
    { private : int  b2 ; } ;
    class  C : public  B1 , public  B2
    {
           public : int  f ( ) ;
    private : int  d ;
    } ;
   
    int main()
    {
        C c;
        //c.b;   // error
        //c.B::b;  // error,从哪里继承的?
        c.B1::b;     // ok,从B1继承的
        c.B2::b;  // ok ,从B2继承的
       
        while(1);
        return 0;
    }

例子程序3代码说明:

//c.b;   // error
//c.B::b;  // error,从哪里继承的?

编译错误,对于类C的b来说,C++无法识别出是类B1的,还是从类B2中继承而来,所以,导致“多次继承产生的二义性”。

这种情况,需要通过虚函数来解决。


6. 虚基类
    (1). 虚基类的引入:
       正如derivedTest3.cpp一样,如果一个派生类从多个基类派生,而这些基类又有一个共同的基类,则在对该基类中声明的名字进行访问时,可能产生二义性。   
       为了保证基类成员在派生类中只继承一次,就必须将在其直接派生类都说明为按虚拟方式派生,即使用关键字virtual 把它们定义为虚基类,格式如下:
       class 派生类名: virtual 派生方式 基类名 {
             ...
       };
       这里,virtual 与派生方式(public, private, protected)间的先后顺序无关。
       例子程序4:虚基类举例:

    /* IDE环境: Dev-C++ 4.9.9.2 */
    /* file: virtualBaseClassTest1.cpp */
    /*例子程序4:虚基类举例 */

    #include <stdio.h>
    class  A
    { public :  A ( )
     { printf("class A/n"); } } ;
    
    class  B : virtual  public  A
    { public :  B ( )
    { printf("class B/n");  } } ;
   
    class  C :  virtual  public  A
    { public :  C ( )
     {printf("class C/n");  } } ;
    
    class  D :  public  B ,  public  C
    { public :  D ( )
    { printf("class D/n"); } } ;
   
    int main ( )
    { D  dd  ; while(1); return 0; }
   
    输出结果:
    class A
    class B
    class C
    class D

例子程序4代码说明:

对于D d的构造过程,依次调用如下类的构造函数:ABCD

       
    (2). 虚基类的初始化:
         a.   从虚基类直接或间接继承的派生类中的构造函数的成员初始化列表中都要列出这个虚基类构造函数的调用(例virtualBaseClassTest2)。
         b.   虚基类的构造函数要在其派生类的构造函数之前调用(例virtualBaseClassTest2)。
         c.   在虚基类的类层次结构中,系统将自左向右按深度优先遍历算法对公共派生类进行初始化(例virtualBaseClassTest3)。
 
    例子程序5:虚基类的初始化举例:

    /* IDE环境: Dev-C++ 4.9.9.2 */
    /* file: virtualBaseClassTest2.cpp */
    /*例子程序5:虚基类的初始化举例:*/
   
    #include <stdio.h>
    class  A
    {
    public:
        A( ) { printf("A() /n"); };  //这里,即使不显示定义A的构造函数,在定义派生类D的一个实例时,就会调用A的默认构造函数
    };
    
    class  B
    {
    public :
        B( ) { printf("B() /n"); }; //显示默认构造函数
    };
   
    class  C
    {
    public :
        C(int i) { printf("C(int i), i =%d /n", i); }; 
    };
   
    class D: virtual public A, virtual public B, virtual public C
    {
    public:
        //D(){ };            // F:/devcpptest/devcpptest/virtualBaseClassTest2.cpp no matching function for call to `C::C()'
                            // candidates are: C::C(const C&)
        D(int i):C(i) { printf("D(int i), i =%d /n", i);};  // 必须用初始化列表的形式,使得在C(i)在派生类D的构造函数执行之前被调用。

     };
   
    int main ( )
    {
        D d(3);
        while(1);
        return 0;
    }
   
    输出结果:
    A()
    B()
    C(int i), i =3
    D(int i), i =3

例子程序5代码说明:

对于D d的构造过程,依次调用如下类的构造函数:ABCD


   
    例子程序6:虚基类的初始化举例3:


    /* IDE环境: Dev-C++ 4.9.9.2 */
    /* file: virtualBaseClassTest3.cpp */
    /* 例子程序6:虚基类的初始化举例3*/

   
    #include <stdio.h>
    class  A
    {
    public:
        A( ) { printf("A() /n"); };  //这里,即使不显示定义A的构造函数,在定义派生类D的一个实例时,就会调用A的默认构造函数
    };
    
    class  B
    {
    public :
        B( ) { printf("B() /n"); }; //显示默认构造函数
    };
   
    class  C:  virtual public A, virtual public B
    {
    public :
        C(int i) { printf("C(int i), i =%d /n", i); }; 
    };
   
    class D: virtual public A, virtual public B
    {
    public:
        //D(){ };            // F:/devcpptest/devcpptest/virtualBaseClassTest3.cpp no matching function for call to `C::C()'
                            // candidates are: C::C(const C&)
        D(int i){ printf("D(int i), i =%d /n", i);};  // 必须用初始化列表的形式,使得C(i)先被调用。
     };
    
    class E: virtual public C, virtual public D
    {
    public:
        //E(){ };            // 原理同 virtualBaseClassTest1.cpp
        //E(int i):{ printf("E(int i), i =%d /n", i);};        // 原理同 virtualBaseClassTest2.cpp,没有进行 C(i),D(i)的初始化
        //E(int i):C(i) { printf("E(int i), i =%d /n", i);};  // 原理同 virtualBaseClassTest2.cpp,没有进行 D(i)的初始化
       
        E(int i):C(i), D(i){ printf("E(int i), i =%d /n", i);};  // 必须用初始化列表的形式,使得C(i),D(i)先被调用。
     };
   
    int main ( )
    {
        E ee(3);
        while(1);
        return 0;
    }   
   
    输出结果:
    A()
    B()
    C(int i), i =3
    D(int i), i =3
    E(int i), i = 3

例子程序6代码说明:

    初始化过程(如下),这也正体现了自左至右深度优先遍历算法:
    1. 初始化C的A;
    2. 初始化C的B;
    3. 初始化C;
    4. D的A与B均已初始化,初始化D;
    5. 初始化E;

 

 


 

使用pytorch构建LSTM_AE模型的两种方式 2.基本LSTM_Unit计算——基本LSTM_AE结构 3.自定义LSTM_Unit计算——自定义LSTM_AE结构 1.LSTM-Encoder-Decoder模型结构及简要解析 图基本lstm计算单元 阅读详情

相关推荐

基于STM32F407的DDS信号源设计与实现:DAC+DMA+TIM的高精度波形生成

本文详细介绍了基于STM32F407微控制器实现高精度DDS信号源的完整方案。通过结合DAC、DMA和TIM外设,并运用DDS算法,实现了分辨率高达0.001Hz的波形生成。文章深入剖析了相位累加器、波表查表等核心原理,提供了从CubeMX配置到代码实战的完整指南,并探讨了性能优化与高频输出问题的解决方案。

weixin_29193259的博客 502

继承与派生(Part Ⅲ)——多重继承 & 虚基类

一个类不仅可以派生出一个派生类,派生类还可以继续派生,形成派生的层次结构。

Miss Z的博客 1356

SwarmClaw:自托管多智能体AI运行时部署与实战指南

多智能体系统是人工智能领域的重要发展方向,它通过多个具备自主决策和协作能力的智能体共同完成任务,其核心原理在于分布式问题求解与协同规划。这种架构在提升任务处理效率、复杂问题分解和鲁棒性方面具有显著技术价值,广泛应用于自动化工作流、虚拟团队协作、智能客服和个性化助手等场景。本文聚焦于SwarmClaw这一自托管的多智能体AI运行时,它原生支持Model Context Protocol,并内置了超过23种AI提供商,为开发者提供了一个开箱即用且高度可定制的控制平面,便于构建和管理复杂的多智能体协作网络。

weixin_27207591的博客 401

虚基类的例子

#include #include #include using namespace std; class Person//虚基类的作用避免重复继承基类中的元素 ,针对一堆多对一的继承结构 { public: Person(string nam,char s,int a) {name=nam;sex=s;age=a;} protected: string name; char sex

zhedahe的专栏 967

PLC凸轮开关指令编程应用——控制算法

凸轮开关指令的作用是在PLC程序中根据凸轮开关(Cam Switch)的状态执行不同的操作。凸轮开关通常是机械式的开关装置,它的位置会随着机械运动的变化而改变。凸轮开关的状态可以用来检测机器的位置、角度或其他相关信息,从而触发相应的控制动作。总结起来,凸轮开关指令是PLC编程中常用的一种控制算法,通过检测凸轮开关的状态来触发相应的操作。本文将介绍凸轮开关指令的应用和相应的控制算法,并提供相关的源代码示例。在这个示例中,凸轮开关状态的值代表不同的位置,根据凸轮开关状态的不同,执行相应的动作。

LiJavascript的博客 1034

YOLO11优化:TGRS2026 CKConv结合C3k2 | 方向特征与跨阶段融合协同,小目标漏检率大幅下降

多尺度适配小目标尺寸变化:在 C3k2 不同阶段配置 CKConv 不同核尺度(浅层小核捕获精细纹理,深层大核聚合上下文),兼顾局部细节与全局感知,提升对舰船、车辆等小尺寸目标及红外热目标的检测鲁棒性。

①答疑群聊服务;②YOLO大模型知识问答系统;③计算机视觉论文生成智能体; 564

【 C++虚基类】

虚基类是C++中解决多重继承中的菱形问题的一种机制。在多重继承时,如果一个类作为多个子类的基类出现,就会出现这个问题。通过声明虚基类,我们可以确保从多个路径继承过来的基类在内存中只有一个实例。. . . };. . . };. . . };. . . };C++中的虚基类是一种重要的语言特性。通过了解和理解虚基类的工作原理,可以更好地利用C++的面向对象特性。

武帝为此的博客 1226

UDF学习(四)FLUENT UDF-DEFINE_PROFILE宏

利用DEFINE_PROFLILE可以指定以下边界或计算域信息:DEFINE_PROFILE(name,t,i)//既可以用。

weixin_44386973的博客 1806

虚基类的简单应用举例

当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类。 在继承中产生歧义的原因有可能是继承类继承了基类多次,从而产生了多个拷贝,即不止一次的通过多个路径继承类在内存中创建了基类成员的多份拷贝。虚基类的基本原则是在内存中只有基类成员的一份拷贝。这样,通过把基类继承声...

芒果summer小仙女 1498

【人工智能】RAG如何根据实际需求选择和进行文档解析(如 PDF、Word、TXT、网页等)?

文档解析的核心在于根据解析目标、文档类型和处理量选择合适工具。PDF、Word、TXT和网页各有特性:PDF需区分可编辑与扫描版,Word需处理结构化内容,TXT简单但需注意编码,网页需应对动态内容。解析场景包括提取纯文本、结构化数据、保留格式和批量处理。非技术用户可借助工具如Adobe Acrobat、WPS和在线OCR,技术用户可通过编程实现自动化。通用流程为:明确目标、分析文档属性、选择工具并测试优化。核心是“工具适配需求”,无需追求万能方案。

奶爸的编程之路,也就一周冷个三天 505

微信小程序 - 解决微信支付报错 requestPayment:fail no permission 原因分析及排查处理(支付失败出错,无法唤起支付弹框面板,微信支付API报错请求付款:失败无权限)

微信小程序,微信支付,支付报错,errMsg: "requestPayment:fail no permission",支付失败,支付权限没问题,微信小程序支付报错,检查了appid正确依旧不行,微信小程序支付异常,苹果ios手机,安卓手机,开发者工具模拟器,最新解决教程,小程序wx.requestPayment报错/无响应,小程序支付 requestPaym,微信小程序认证,真机运行,小程序微信支付提示错误,微信小程序里使用微信支付错误提示,微信小程序支付异常,微信支付弹框拉不起来,小程序支付api,都检

🏆 前端领域优质创作者 1万+

【C++学习笔记】虚基类

文章目录0x00 前言0x01 虚基类 0x00 前言 文章中的文字可能存在语法错误以及标点错误,请谅解; 如果在文章中发现代码错误或其它问题请告知,感谢! 本文档为个人边学习边记录的C++笔记,非教程,笔记中会存在引用他人文章内容的部分,被引用的原文不会被特殊标记出来,但会在参考文档中给出原文链接。 0x01 虚基类 当某类部分或全部直接基类是从另一个共同基类派生而来时,在这些直接基类中从上一级共同基类继承来的成员就有相同的名称。在派生类对象中,这些同名数据成员在内存中同时拥有多个副本,同一个函数名会有多

C/C++攻城狮 449

从 SAP GUI 走向 SAP Fiori:一套面向 SAP S/4HANA 的用户迁移实战方法论

SAP S/4HANA转型中,用户从SAP GUI迁移到Fiori的难点在于业务价值的重构而非简单的界面替换。Fiori的核心价值在于角色化、实时洞察和智能决策,而非完全替代GUI。成功迁移需分阶段推进:先展示关键角色的价值,建立统一入口,再逐步提高Fiori占比。让用户参与设计比后期培训更重要,需通过具体场景(如采购优先级管理)展示效率提升。迁移策略应平衡新旧界面优势,让Fiori成为业务价值触达的主要方式,而非强制替换。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 236

『 C++类与对象 』多态之单继承与多继承的虚函数表

多态是一种基于继承关系的语法,既然涉及到继承,而继承的方式有多种:单继承多继承棱形继承棱形虚拟继承不同的继承方式其虚表的形式也不同;以下操作均为在CentOS7_x64机器上的操作。

小侯宝的博客 439

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

C++多继承与虚继承:从菱形问题到工程实践

多继承是面向对象编程中允许一个类从多个基类继承特性的机制,它通过扩展单继承模型提供了更灵活的对象建模能力。其核心原理在于编译器会将多个基类的内存布局按继承顺序拼接,并通过地址偏移实现指针转换。这一技术的主要价值在于能够直观表达复杂的“是一个”关系,例如水上飞机同时继承船和飞机的特性。然而,多继承也带来了著名的菱形继承问题,即当多个基类共享同一祖先时会导致数据冗余和访问歧义。为解决这一问题,C++引入了虚继承机制,通过共享基类子对象和额外的间接指针来消除冗余,但这也带来了额外的内存和性能开销。在实际应用场景中

weixin_33843409的博客 372

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

python多继承 实例化_Python-面向对象之多继承

1、Python不同版本的类Python2.2之前类是没有共同的祖先的,之后,引入object类,它是所有类的共同祖先类object。Python2 中为了兼容 ,分为古典类,新式类。Python2 中全部都是新式诶新式类都是继承自object的,新式类可以使用superPython2.2新式类:等同 python3,旧式类:不能使用super,只能使用 类名. 调用父类的方法属性, 没有base...

weixin_33268205的博客 465

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

基类和派生类

看了c#的教程,也上网络上搜索基类与派生类的概念,一直没有一个很明确的定义.弄得偶一直很迷糊,现在搜索到c++的教程里倒是有比较明确的说明,特意贴在这里,帮助自己理解.继承机制提供了无限重复利用程序资源的一种途径。  继承使得我们得以用一种简单的方式来定义新类。如果我们定义了一个哺乳动物类,包括哺乳动物的一些普通属性和方法,然后再定义一个狗类, 有没有必要重头开始定义呢?实际上这是没有必要的,

紫藤阁 3万+

Python 多继承与mro

python多继承

qq_42855293的博客 512

C++多继承中指针偏移原理与安全转换实践指南

在C++面向对象编程中,继承是实现代码复用的核心机制。多继承允许一个类同时拥有多个父类的特性,但其底层实现涉及复杂的内存布局。编译器会根据基类声明顺序排列子对象,导致指向派生类对象的基类指针需要进行地址调整,即指针偏移。理解这一原理对编写安全、健壮的代码至关重要,它直接影响虚函数调用、对象生命周期管理和类型转换的正确性。在工程实践中,不当的指针转换(如误用reinterpret_cast)会引发内存访问错误和段故障等严重问题。因此,掌握static_cast、dynamic_cast在不同场景下的行为差异,

weixin_30417487的博客 327

C++ 、java 和 C# 的区别

一、基础类型 c++: ** java:** C#: 1.以java为准,c++里面的int short long 像这样的整型 一般都有unsigned 和signed的区分 ,这个跟java和c# 的区别比较大,但c#里面有unit ulong ushort 这三种就相当于c++的修饰词unsigned,当c++李明的变量类型定义unsigned,就默认是整数。 2.java和c#里面都有字符串型 和byte型, 但c++里面没有,但它是以另外的形式存储这类型的数据的,

程序员ken的博客 1833

python基础进阶1.7:__del__()方法,继承,重写,多态,类属性、实例属性用法讲解

保护对象的属性 如果有一个对象,当需要对其进行修改属性时,有2种方法 对象名.属性名 = 数据 ---->直接修改 对象名.方法名() ---->间接修改 为了更好的保存属性安全,即不能随意修改,一般的处理方式为 将属性定义为私有属性 添加一个可以调用的方法,供调用 class People(object): def __init__(self, name): ...

haosen 1675

C++多继承下虚函数表(vtable)内存布局与vptr机制详解

虚函数表(vtable)是C++实现运行时多态的核心机制,通过存储虚函数地址实现动态绑定。在单继承中,对象包含一个vptr指向vtable;而在多继承场景下,派生类对象会包含多个vptr,分别指向不同基类的vtable。编译器通过生成调整跳板(thunk)代码处理this指针偏移,确保通过不同基类指针调用虚函数时能正确跳转到最终派生类实现。理解vtable布局对排查多继承下的对象切片、指针偏移等内存问题至关重要,也是优化高性能C++代码的基础。本文结合调试实例,深入解析多继承vptr的初始化过程和构造/析构

weixin_34234829的博客 351

C++虚函数表内存布局解析:从原理到多继承实战

虚函数表是C++实现运行时多态的核心机制,它本质上是一个存储虚函数指针的数组。其工作原理是通过每个对象内部的虚函数表指针,在运行时动态查找并调用正确的函数实现,从而实现动态绑定。这项技术的核心价值在于提升代码的扩展性和可维护性,允许通过基类接口操作不同的派生类对象。在图形渲染、框架设计等需要灵活处理多种对象类型的应用场景中,虚函数表机制至关重要。本文通过一个实际的多继承崩溃案例,深入剖析了虚函数表在单一继承、多重继承下的内存布局差异,特别是基类指针偏移量计算错误导致的虚函数表指针错位问题,并提供了使用调试器

weixin_30781107的博客 403

Python下的多继承

优雅地对待Python中的多继承

_刘振华_的专栏 1705

告别方向盘硬连接:手把手拆解Steer-By-Wire线控转向的ECU与传感器协同工作原理

本文深入解析了Steer-By-Wire(SBW)线控转向技术的核心工作原理,重点探讨了ECU与传感器的协同机制。通过拆解SBW系统的三大核心模块和实时控制算法,揭示了如何实现毫秒级响应的闭环控制与安全冗余设计,为嵌入式开发工程师提供了宝贵的实战参考。

weixin_30520015的博客 292

深入理解C++ 虚函数表

深入理解C++ 虚函数表 目录 深入理解C++ 虚函数表 虚函数表概述 单继承下的虚函数表 派生类未覆盖基类虚函数 派生类覆盖基类虚函数 多继承下的虚函数表 无虚函数覆盖 派生类覆盖基类虚函数 钻石型虚继承 总结 几个原则 安全性问题 ​ C++中的虚函数的作用主要是实现了多态的机制。关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实际子类的成员函数。 Copy Derive ...

大隐隐于野 170
上一篇: Android系统源码分析-进程间通信机制binder(一):守护进程servicemanager
下一篇: Android四大组件之Android Service的用法
liranke
博客等级 码龄20年 4939粉丝 594原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liranke

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值