C++核心编程之类和对象---C++面向对象的三大特性--多态

目录

一、多态

1. 多态的概念

2.多态的分类:

1. 静态多态:

2. 动态多态:

 3.静态多态和动态多态的区别:

4.动态多态需要满足的条件:

4.1重写的概念:

4.2动态多态的调用:

二、多态

三、多态的深入剖析

四、利用多态写一个模拟计算器案例

1.普通方式写一个模拟计算器

2.利用多态的方式写一个计算器

五、纯虚函数和抽象类

抽象类特点:

六、利用多态的抽象类写一个饮品制作流程的案例

七、纯析构和纯虚析构

虚析构和纯虚析构的共性:

虚析构和纯虚析构的区别:

总结:

八、利用多态写一个组装电脑的案例


一、多态

1. 多态的概念

计算机程序运行时,相同的消息可能会送给多个不同的类别之对象,而系统可依据对象所属类别,引发对应类别的方法,而有不同的行为。简单来说,所谓多态意指相同的消息给予不同的对象会引发不同的动作。

多态也可定义为“一种将不同的特殊行为和单个泛化记号相关联的能力”。

多态可分为变量多态与函数多态。变量多态是指:基类型的变量(对于C++是引用或指针)可以被赋值基类型对象,也可以被赋值派生类型的对象。函数多态是指,相同的函数调用界面(函数名与实参表),传送给一个对象变量,可以有不同的行为,这视该对象变量所指向的对象类型而定。因此,变量多态是函数多态的基础。 

多态是c++面向对象的三大特性之一

2.多态的分类:

1. 静态多态:

      函数重载 和 运算符重载 属于静态多态,复用函数名

     静态多态(static polymorphism):模板也允许将不同的特殊行为和单个泛化记号相关联,由于这种关联处理于编译期而非运行期,因此被称为“静态”。可以用来实现类型安全、运行高效的同质对象集合操作。C++STL不采用动态多态来实现就是个例子。

  • 函数重载(Function Overloading)

  • 运算符重载(Operator Overloading)

  • 带变量的宏多态(macro polymorphism)

  • 非参数化多态或译作特设多态(Ad-hoc polymorphism):

  • 参数化多态(Parametric polymorphism):把类型作为参数的多态。在面向对象程序设计中,这被称作泛型编程。

2. 动态多态:

    派生类 和 虚函数 实现运行时多态

   动态多态(dynamic polymorphism):通过类继承机制和虚函数机制生效于运行期。可以优雅地处理异质对象集合,只要其共同的基类定义了虚函数的接口。也被称为子类型多态(Subtype polymorphism)或包含多态(inclusion polymorphism)。在面向对象程序设计中,这被直接称为多态。

对于C++语言,带变量的宏和函数重载(function overload)机制也允许将不同的特殊行为和单个泛化记号相关联。然而,习惯上并不将这种函数多态(function polymorphism)、宏多态(macro polymorphism)展现出来的行为称为多态(或静态多态),否则就连C语言也具有宏多态了。谈及多态时,默认就是指动态多态,而静态多态则是指基于模板的多态。

 3.静态多态和动态多态的区别:

        1. 静态多态的函数地址早绑定,编译阶段确定函数地址

        2. 动态多态的函数地址晚绑定,运行阶段确定函数地址

4.动态多态需要满足的条件:

        1.有继承关系

        2.子类中重写父类的虚函数(子类中写不写virtual都可以)

4.1重写的概念:

        函数返回值类型  函数名  参数列表都完全相同。

        注意:与函数重载要区分。

4.2动态多态的调用:

        父类的指针或引用  执行子类对象

二、多态

示例:

#include<iostream>

using namespace std;

// 多态

 

// 动态多态的满足条件

// 1. 有继承关系

// 2. 子类要重写父类的虚函数

 

// 动态多态的使用

// 父类的指针或引用  指向子类对象

 

// 动物类

class Animal

{

public:

    // 虚函数

    virtual void speak()

    {

        cout<<"动物在说话"<<endl;

    }

};

 

// 猫类

class Cat:public Animal

{

public:

    // 重写  函数返回值类型  函数名 参数列表要   完全相同

    void speak()

    {

        cout<<"猫在说话"<<endl;

    }

};

 

// 狗类

class Dog:public Animal

{

public:

    void speak()

    {

        cout<<"狗在说话"<<endl;

    }

};

 

// 执行说话的函数

void dospeak(Animal &animal) // Animal & animal  =  cat;

{

    // 地址早绑定  在编译阶段确定函数地址

 

    // 如果要执行猫说话,那么这个函数地址就不能提前绑定

    // 需要在运行阶段进行绑定,地址晚绑定

    animal.speak();

}

 

// c++允许父类和子类的转化

void test01()

{

    Cat cat;

    // cat.speak();

    dospeak(cat);  // 父类的引用,接收的是子类的对象

 

    Dog dog;

    dospeak(dog);

}

 

int main()

{

    test01();

    return 0;

}

没写 virtual 之前是地址早绑定

写入虚函数后,地址晚绑定运行结果:

 

三、多态的深入剖析

图解示例:

示例:

#include<iostream>

using namespace std;

// 多态的底层逻辑



// 动物类

class Animal

{

public:

    // 虚函数

    void speak()

    {

        cout << "动物在说话" << endl;

    }

};



// 猫类

class Cat :public Animal

{

public:

    // 重写  函数返回值类型  函数名 参数列表要   完全相同

    void speak()

    {

        cout << "猫在说话" << endl;

    }

};



// 狗类

class Dog :public Animal

{

public:

    void speak()

    {

        cout << "狗在说话" << endl;

    }

};



// 执行说话的函数

void dospeak(Animal& animal)

{

    // 地址早绑定  在编译阶段确定函数地址

    // 如果要执行猫说话,那么这个函数地址就不能提前绑定

    // 需要在运行阶段进行绑定,地址晚绑定

    animal.speak();

}



// c++允许父类和子类的转化

void test01()

{

    Cat cat;

    // cat.speak();

    dospeak(cat);  // 父类的引用,接收的是子类的对象



    Dog dog;

    dospeak(dog);

}



void test02()

{

        cout << "Animal 类的大小:" << sizeof(Animal) << endl;

}

int main()

{

    test01();

    test02();

    return 0;

}

通过命令提示符查看

加入虚函数后

子类在没有重写的时候

子类重写虚函数后

没加virtual的类的大小,相当于空类,大小是1

变为虚函数后的类的大小为8/4(看你的编译器是多少位的),类的大小是一个指针的大小

关于命令提示符查看类可查询上一篇文章:命令提示符查看类

四、利用多态写一个模拟计算器案例

多态的优点:

  • 代码组织结构清晰
  • 可读性强
  • 利于前期和后期的扩展及维护

1.普通方式写一个模拟计算器

示例1:

#include<iostream>

using namespace std;

// 分别利用普通写法和多态的技术实现计算器的功能

 

// 普通的写法

class Calculator

{

public:

    int get_result(string oper)

    {

        if(oper == "+")

            return m_num1+m_num2;

        if(oper == "-")

            return m_num1 - m_num2;

        if(oper == "*")

            return m_num1 * m_num2;

        if(oper == "/")

            return m_num1 / m_num2;

    }

    int m_num1;

    int m_num2;

};

void test01()

{

    Calculator c;

    c.m_num1 = 40;
    
    c.m_num2 = 20;

 

    // 开闭原则,对扩展进行开放,对修改进行关闭

 

    cout<<c.m_num1<<" + "<<c.m_num2<<" = "<<c.get_result("+")<<endl;

    cout<<c.m_num1<<" - "<<c.m_num2<<" = "<<c.get_result("-")<<endl;

    cout<<c.m_num1<<" * "<<c.m_num2<<" = "<<c.get_result("*")<<endl;

    cout<<c.m_num1<<" / "<<c.m_num2<<" = "<<c.get_result("/")<<endl;

}

int main()

{

    test01();

    return 0;

}

运行结果:

2.利用多态的方式写一个计算器

示例2:

#include<iostream>

using namespace std;

// 利用多态实现计算器

class Abstract_Calculator

{

public:

    virtual int get_result()

    {

        return 0;

    }
    
    int num1;

    int num2;

};

 

// 设计一个加法计算器的类

class Add_Calculator:public Abstract_Calculator

{

public:

    int get_result()

    {

        return num1+num2;

    }

};

// 设计一个减法计算器的类

class Sub_Calculator:public Abstract_Calculator

{

public:

    int get_result()

    {

        return num1-num2;

    }

};

// 设计一个乘法计算器的类

class Mul_Calculator:public Abstract_Calculator

{

public:

    int get_result()

    {

        return num1*num2;

    }

};

 

void test02()

{

    // 多态的使用条件

    // 父类的指针或引用指向子类对象

    // 加法运算
        
    Abstract_Calculator *abc = new Add_Calculator;

    abc->num1 = 100;

    abc->num2 = 200;

    cout<<abc->num1<<" + "<<abc->num2<<" = "<<abc->get_result()<<endl;

    // 堆区数据用完记得销毁

    delete abc;

 

    // 减法运算

    abc = new Sub_Calculator;

    abc->num1 = 200;

    abc->num2 = 100;

    cout<<abc->num1<<" - "<<abc->num2<<" = "<<abc->get_result()<<endl;

    delete abc;

 

    // 乘法运算

    abc = new Mul_Calculator;

    abc->num1 = 200;

    abc->num2 = 100;

    cout<<abc->num1<<" * "<<abc->num2<<" = "<<abc->get_result()<<endl;

    delete abc;

}

int main()

{

    test02();

    return 0;

}

运行结果:

五、纯虚函数和抽象类

在多态中,通常父类中虚函数的实现是毫无意义的,主要是调用子类的重写内容

因此可以将虚数改为纯虚数

纯虚数语法: virtual 返回值类型 函数名(参数列表) =  0 ;

当类中有了纯虚函数,这个类称为抽象类

抽象类特点:

  1. 无法实例化对象
  2. 子类必须重写抽象类中的纯虚函数,否则也属于抽象类

示例:

#include<iostream>

using namespace std;

// 纯虚数抽象类

class Base

{

public:

    virtual void func() = 0; // 虚函数的基础上才可以等于0,纯虚函数

    // 只要有一个纯虚数,这个类称为抽象类
    
};

 

// 抽象类的子类,必须要重写父类中的纯虚函数,否则也是抽象类,无法实例化对象

class Son:public Base

{

public:

    void func()

    {

        cout<<"func函数调用"<<endl;

    }

};

void test01()

{

    // Base b; 无法实例化一个抽象类

    // new 一个也不行

    Base *base = new Son;

    base->func();

}

int main()

{

    test01();

    return 0;

}

运行结果:

六、利用多态的抽象类写一个饮品制作流程的案例

案例描述:利用多态技术,提供抽象类制作饮品基类,提供子类制作咖啡和茶叶

示例:

#include<iostream>

using namespace std;

class Abstract_Drinking

{

public:

    // 煮水

    virtual void Boil() = 0;

    // 冲泡

    virtual void Brew() = 0;

    // 倒入杯中

    virtual void Pour_Cup() = 0;

    // 加入辅助佐料

    virtual void Put_something() = 0;

    // 制作饮品

    void make_drink()

    {

        Boil();

        Brew();

        Pour_Cup();

        Put_something();

    }

};

 

// 具体的制作

// 咖啡

class Coffee:public Abstract_Drinking

{

public:

    // 煮水

    virtual void Boil()

    {

             cout<<"煮矿泉水"<<endl;

    }

    // 冲泡

    virtual void Brew()

    {

        cout<<"冲泡咖啡"<<endl;

    }

    // 倒入杯中

    virtual void Pour_Cup()

    {

        cout<<"倒入杯中"<<endl;

    }

    // 加入辅助佐料

    virtual void Put_something()

    {

        cout<<"加入糖和牛奶"<<endl;

    }

};

 

// 茶

class Tea:public Abstract_Drinking

{

public:

    // 煮水

    virtual void Boil()

    {

             cout<<"煮矿泉水"<<endl;

    }

    // 冲泡

    virtual void Brew()

    {

        cout<<"冲泡茶叶"<<endl;

    }

    // 倒入杯中

    virtual void Pour_Cup()

    {

        cout<<"倒入杯中"<<endl;

    }

    // 加入辅助佐料

    virtual void Put_something()

    {

        cout<<"加入柠檬,枸杞"<<endl;

    }

};

 

// 制作

void do_work(Abstract_Drinking * abd)

    // Abstract_Drinking *abd = new Coffee  父类指针指向子类对象

{

    abd->make_drink();

    delete abd;// 在堆区制作完记得释放

}

 

void test01()

{

    // 制作咖啡

    do_work(new Coffee);

 

    cout<<"-------------"<<endl;

    // 制作茶

    do_work(new Tea);

}

int main()

{

    test01();

    return 0;

}

运行结果:

七、纯析构和纯虚析构

问题:多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码。

解决办法:将父类中的析构函数改为**虚析构**或者**纯虚析构**

虚析构和纯虚析构的共性:

  • 可以解决父类指针释放子类对象
  • 都需要有具体的函数实现

虚析构和纯虚析构的区别:

  • 如果是纯虚析构,该对象属于抽象类,无法实现实例化对象

**虚析构语法:**

virtual ~类名(){}

**纯虚析构语法:**

virtual ~类名()= 0;

类名::~类名(){} // 类内声明,类外实现

示例:

#include<iostream>

using namespace std;

// 虚析构和纯虚析构

class Animal

{

public:

    Animal()

    {

        cout<<"Animal的构造函数的调用"<<endl;

    }

    virtual void speak() = 0;// 变为纯虚函数

 

    // 利用虚析构可以解决  父类指针释放子类对象时不干净的问题

    /*

    virtual ~Animal()

    {

        cout<<"Animal虚析构函数的调用"<<endl;

    }

    */

 

    virtual ~Animal() = 0;

    // 纯虚析构

    // 需要声明  也需要实现

    // 有了纯虚析构之后,那么这个类也属于抽象类,无法实现实例化对象

};

Animal::~Animal()

{

    cout<<"Animal纯虚析构函数的调用"<<endl;

}

 

class Cat: public Animal

{

public:

    Cat(string name)

    {

        cout<<"这是Cat的构造函数的调用"<<endl;

        this->name = new string(name);

    }

    void speak()

    {

        cout<<*name<<"小猫在说话"<<endl;

    }

    ~Cat()

    {

        if(this->name!=NULL)

        {

            cout<<"这是Cat的析构函数的调用"<<endl;

            delete this->name;

            this->name = NULL;

        }

    }

    string *name;// 创建在堆区

};

 

void test01()

{

    Animal *animal = new Cat("Tom");

    animal->speak();

    // 父类的指针在析构的时候不会调用子类的析构函数

    // 导致子类如果在堆区有数据,会出现内存泄漏的情况

    delete animal;

}

int main()

{

    test01();

    return 0;

}

运行结果:

总结:

  1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象
  2. 如果子类中没有堆区数据,可以不写为虚析构或者纯虚析构
  3. 拥有纯虚析构函数的类也属于抽象类

八、利用多态写一个组装电脑的案例

案例说明:

电脑主要组成部件为CPU(用于计算),显卡〔用于显示),内存条〔用于存储)

将每个零件封装出抽象基类,并且提供不同的厂商生产不同的霉件,例如Intel厂商和Lenovo厂商

创建电脑类提供让电脑工作的函数,并且调用每个零件工作的接口

测试时组装三台下同的电脑进行工作

示例:

#include<iostream>

using namespace std;

 

// 抽象不同零件的类

// 计算机类

class CPU

{

public:

    // 抽象的计算函数

    virtual void calculate() = 0;

};

// 显卡类

class Video_Card

{

public:

    // 抽象的显示函数

    virtual void display() = 0;

};

// 内存条类

class Memory

{

public:

    // 抽象的存储函数

    virtual void storage() = 0;

};

 

// 提供电脑类

class Computer

{

public:

    Computer(CPU* cpu, Video_Card* vc, Memory* mem)

    {

        this->cpu = cpu;

        this->vc = vc;

        this->mem = mem;

    }

 

    // 提供工作函数

    void work()

    {

        // 让零件工作起来,调用接口

        this->cpu->calculate();

        this->vc->display();

        this->mem->storage();

    }

 

    // 提供析构函数  释放在堆区创建的三个零件

    ~Computer()

    {

        if(cpu!=NULL){

            delete cpu;

            cpu = NULL;

        }

        if(vc!=NULL){

            delete vc;

            vc = NULL;

        }

        if(mem!=NULL){

            delete mem;

            mem = NULL;

        }

}

 

private:

    CPU* cpu;  // CPU的零件指针

    Video_Card* vc;  // 显卡的零件指针

    Memory* mem;  // 内存条的零件指针

};

 

// 具体厂商

// Intel厂商

// CPU

class Intel_CPU :public CPU

{

public:

    void calculate()

    {

        cout << "这是Intel厂商的CPU,并且开始计算了" << endl;

    }

};

// 显卡

class Intel_Video_Card :public Video_Card

{

public:

    void display()

    {

        cout << "这是Intel厂商的显卡,并且开始显示了" << endl;

    }

};

// 内存条

class Intel_Memory :public Memory

{

    void storage()
    
    {

        cout << "这是Intel厂商的内存条,并且开始存储了" << endl;

    }

};

 

 

// Lenovo厂商

// CPU

class Lenovo_CPU :public CPU

{

public:

    void calculate()

    {

        cout << "这是Lenovo厂商的CPU,并且开始计算了" << endl;

    }

};

// 显卡

class Lenovo_Video_Card :public Video_Card

{

public:

    void display()

    {

        cout << "这是Lenovo厂商的显卡,并且开始显示了" << endl;

    }

};

// 内存条

class Lenovo_Memory :public Memory

{

    void storage()

    {

        cout << "这是Lenovo厂商的内存条,并且开始存储了" << endl;

    }

};

 

 

void test01()

{

    cout<<"------------------------"<<endl;

    cout<<"第一台电脑开始工作"<<endl;
    
    // 创建第一台电脑的零件

    CPU* intel_CPU = new Intel_CPU;

    Video_Card* intel_videocard = new Intel_Video_Card;

    Memory* intel_memory = new Intel_Memory;

    // 创建电脑零件的时候时在堆区创建的

 

    // 创建第一台电脑

    Computer* computer1 = new Computer(intel_CPU, intel_videocard, intel_memory);

    computer1->work();

    delete computer1;

 

    cout<<"-----------------------"<<endl;

    cout<<"第二台电脑开始工作"<<endl;

    // 组装第二台电脑

    Computer* computer2 = new Computer(new Lenovo_CPU, new Lenovo_Video_Card, new Lenovo_Memory);

    computer2->work();

    delete computer2;

 

    cout<<"-----------------------"<<endl;

    cout<<"第三台电脑开始工作"<<endl;

    // 组装第三台电脑

    Computer* computer3 = new Computer(new Lenovo_CPU, new Intel_Video_Card, new Lenovo_Memory);

    computer3->work();

    delete computer3;

}

int main()

{

    test01();

    return 0;

}

运行结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/327317.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Git 使用与问题记录 二(公司快速上手版)

写在前面 记录自己学习的内容&#xff0c;方便后面忘记的时候查看。给像我一样的新手提供一点参考 正文 上一章已经安装好了Git&#xff0c;如何使用呢。我这里会分享两种办法&#xff0c;第一种是在VS2022中克隆代码&#xff0c;修改和提交&#xff1b;第二种是用命令提交。…

Linux Centos7静默安装(非图形安装)Oracle RAC 11gR2(Oracle RAC 11.2.0.4)

Oracle RAC (全称Oracle Real Application Clusters &#xff09;静默安装&#xff08;非图形安装&#xff09;教程。 由于这篇文章花费了我太多时间&#xff0c;设置了仅粉丝可见&#xff0c;见谅。 环境说明&#xff1a; 虚拟机软件&#xff1a;VMware Workstation 16 Pro…

Java IO流

目录 一.字符集 二.JavaIo流体系 三.如何提升读取和写入速度&#xff1f; 四.文件读取乱码问题 一.字符集 ASCII:一个字节存储&#xff0c;首尾是0 GBK: 两个字节存储&#xff0c;首位是1 Unicode:统一码&#xff0c;4个字节存储&#xff0c;容纳世界所有文字 UTF-8:Un…

acwing 图的深度搜索DFS

写目录 邻接表的构建邻接表DFSAcWing 846. 树的重心无向图 pat 1034 Head of a Gang有向图的深度搜索&#xff0c;各连通块分别搜索 邻接表的构建 邻接表DFS const int N 1e5 10, M 2*N; int h[N], e[M], ne[M]; // h[N]: 顶点Ni的第一个连接点 bool visited[M]; …

机器学习周报第27周

目录 摘要Abstract一、文献阅读 摘要 本周阅读了一篇混沌时间序列预测的论文&#xff0c;论文模型主要使用的是时间卷积网络&#xff08;Temporal Convolutional Network&#xff0c;TCN&#xff09;、LSTM以及GRU。在数据集方面除了使用现实的时间序列数据外&#xff0c;还通…

接口防刷方案

1、前言 本文为描述通过Interceptor以及Redis实现接口访问防刷Demo 2、原理 通过ip地址uri拼接用以作为访问者访问接口区分 通过在Interceptor中拦截请求&#xff0c;从Redis中统计用户访问接口次数从而达到接口防刷目的 如下图所示 3、案例工程 项目地址&#xff1a; htt…

MongoDB Compass当前版本及历史版本下载安装

mongoDB compass 当前版本下载 官网 https://www.mongodb.com/try/download/compass 官网下载一般只能下载最新版本。 github https://github.com/mongodb-js/compass MongoDB Compass与MongoDB的版本对应关系 MongoDB CompassMongoDB1.9.12MongoDB 2.6.11 Community

STM32H5 Nucleo-144 board开箱

文章目录 开发板资料下载 【目标】 点亮LD1&#xff08;绿&#xff09;、LD2&#xff08;黄&#xff09;和LD3&#xff08;红&#xff09;三个LED灯 【开箱过程】 博主使用的是STM32CubeMX配置生成代码&#xff0c;具体操作如下&#xff1a; 打开STM32CubeMX&#xff0c;File-…

快速知识付费平台搭建,一分钟搭建你的专属知识服务平台

产品服务 线上线下课程传播 线上线下活动管理 项目撮合交易 找商机找合作 一对一线下交流 企业文化宣传 企业产品销售 更多服务 实时行业资讯 动态学习交流 分销代理推广 独立知识店铺 覆盖全行业 个人IP打造 独立小程序 私域运营解决方案 公域引流 营销转化 …

vue前端开发自学,使用yarn脚手架创建vue项目

vue前端开发自学,使用yarn脚手架创建vue项目&#xff01;下面展示一下&#xff0c;如何在本机操作&#xff0c;使用yarn这款脚手架&#xff0c;创建一个vue项目。 第一步&#xff0c;你需要先创建好&#xff0c;即将存档项目的文件夹。我的路径是在&#xff1a;"D:\yarn\…

C++ OJ基础

C OJ基础 在学校学习C程序设计基础课程的OJ题目 缺少第二十题 这里写目录标题 C OJ基础习题练习(一)打印图形习题练习(二)数据的输入输出习题练习(三)函数重载习题练习(四)设计矩形类习题练习(五)定义Tree类习题练习(六)完善职工工资类Salary的设计习题练习(七)设计矩形类recta…

2、BERT:自然语言处理的变革者

请参考之前写的&#xff1a;2、什么是BERT&#xff1f;-CSDN博客文章浏览阅读826次&#xff0c;点赞19次&#xff0c;收藏22次。BERT&#xff08;Bidirectional Encoder Representations from Transformers&#xff09;是Google在2018年提出的一种自然语言处理&#xff08;NLP&…

直流电机闭环调速实验

直流电机闭环调速实验 直流电机闭环调速系统是一个典型的按偏差调节的闭环控制系统&#xff0c;通过系统的调节&#xff0c;使电机的转速与期望的给定速度一致。 本次实验我们就以AEDK-LabACT 自控/计控原理实验箱中的直流电机为对象&#xff0c;分析讨论直流电机闭环调速系统设…

java日志框架总结

一、日志框架简单分类介绍 java常用的日志框架、可以分为两组&#xff1a; 1、JCL、JUL、Log4j&#xff1b; 2、SLF4J、Log4j2、Logback&#xff1b; 其中第一组是比较早期的日志实现框架&#xff0c;JCL并不是具体的日志实现框架&#xff0c;JCL其实是定义了一…

cad的模型怎么打散导入3d---模大狮模型网

将CAD中的模型打散并导入3D建模软件&#xff0c;需要以下步骤&#xff1a; 将CAD中的模型进行分组或分层&#xff1a;在CAD中&#xff0c;将模型按照不同的组或层进行分组或分层。这样可以方便地控制每个部分的显示和隐藏&#xff0c;在导入3D建模软件后&#xff0c;也可以更方…

运维知识点-Sqlite

Sqlite 引入 依赖 引入 依赖 <dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.36.0.3</version></dependency>import javafx.scene.control.Alert; import java.sql.*;public clas…

【FastAPI】请求体

在 FastAPI 中&#xff0c;请求体&#xff08;Request Body&#xff09;是通过请求发送的数据&#xff0c;通常用于传递客户端提交的信息。FastAPI 使得处理请求体变得非常容易。 请求体是客户端发送给 API 的数据。响应体是 API 发送给客户端的数据 注&#xff1a;不能使用 …

通过 C++/WinRT 使用 API

如果 API 位于 Windows 命名空间中 这是你使用 Windows 运行时 API 最常见的情况。 对于元数据中定义的 Windows 命名空间中的每个类型&#xff0c;C/WinRT 都定义了 C 友好等效项&#xff08;称为投影类型 &#xff09;。 投影类型具有与 Windows 类型相同的完全限定名称&…

报名活动怎么做_小程序创建线上报名活动最详细攻略

报名活动怎么做&#xff1a;一篇让你掌握活动策划与营销的秘籍 在当今社会&#xff0c;无论是线上还是线下&#xff0c;活动已经成为企业营销和品牌推广的重要手段。但是&#xff0c;如何策划一场成功的活动呢&#xff1f;这篇文章将为你揭示活动策划与营销的秘籍&#xff0c;…

Python代码调试的几种方法总结

使用 pdb 进行调试 pdb 是 python 自带的一个包&#xff0c;为 python 程序提供了一种交互的源代码调试功能&#xff0c;主要特性包括设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb 提供了一些常用的调试命令&#xff0c;详情见表 1。…