我的世界Java版1.21.4的Fabric模组开发教程(二十三)创建生物(下)实体在游戏中的实现(1)

我的世界Java版1.21.4的Fabric模组开发教程(二十三)创建生物(下)实体在游戏中的实现(1)

这是适用于Minecraft Java版1.21.4的Fabric模组开发系列教程专栏第二十三章——创建生物(下)实体在游戏中的实现(1)。如果还未开始制作生物的外观和动画,请参考我的世界Java版1.21.4的Fabric模组开发教程(二十二)创建生物(上)实体外观与动画设计。想要阅读其他内容,请查看或订阅上面的专栏。

在上一章节中,我们完成了测试生物(test_entity) 的外观与动画设计,并导出了实体模型文件、实体动画文件和实体平面展开图。接下来,我们将使用这些文件,将生物真正的加入到游戏中。

即使在前一章中完成了创建实体的准备工作,想要在游戏中添加实体依然非常繁琐。一般,我们按照下面每个步骤需要完成的具体工作为顺序依次推进:

  • 注册实体模型层
    • 创建实体模型层静态常量;
    • 编写实体渲染状态类;
    • 导入实体模型类;
  • 注册实体及其模型渲染器
    • 创建实体注册键静态常量;
    • 编写实体类;
    • 注册实体;
    • 编写实体模型渲染器类;
  • 注册实体属性
    • 定义实体属性;
  • 完成创建实体的其他工作;

为实体添加动画也是必不可少的步骤。尤其是生物行走时,如果没有动画,生物会直接向四面八方平移。要为实体添加动画,请按照以下步骤推进:

  • 导入实体动画类;
  • 在实体模型类中完成动画设置;

简单的说,在游戏中添加实体就是分别注册实体模型层、实体渲染器和实体属性并设置动画的过程,所有代码均需要在客户端模块中完成。

如果已经完成了注册实体模型层和注册实体及其模型渲染器两节内容,请参考我的世界Java版1.21.4的Fabric模组开发教程(二十四)创建生物(下)实体在游戏中的实现(2)。

第一节——注册实体模型层

实体模型层的注册大致分为创建实体模型层静态常量(1.1)、编写实体渲染状态类(1.2)、导入实体模型类(1.3) 以及注册实体模型层(1.4) 四个步骤。

1.1创建实体模型层静态常量

实体模型层的注册是创建生物的第一步。我们可以创建一个实体模型层类,在其中声明实体模型层静态常量,用于为指定生物的模型层注册。


实体模型层记录类EntityModelLayer

EntityModelLayer记录类用于为指定生物创建实体模型层,使其在游戏中正常显示。一个生物可以有一个或多个实体模型层,多个实体模型层可以为生物的不同部位提供渲染空间。

实体模型层记录类中只有一个带参构造方法用于创建其对象,参数列表已经在类头处体现:

@Environment(EnvType.CLIENT)publicrecordEntityModelLayer(Identifier id,String name){publicStringtoString(){returnthis.id +"#"+this.name;}}
  • Identifier id:标识符,传递一个Identifier对象;
  • String name:实体模型层名称,可以指定实体的部位,如果模型层只用来创建一个实体,此处应传递“main”;

1.在客户端模块中创建entity目录,然后在其中创建实体模型层类ModModelLayers

在这里插入图片描述


2.在类中声明名为TEST_ENTITY的实体模型层静态常量,然后调用EntityModelLayer记录类的构造方法对其初始化;

publicstaticfinalEntityModelLayerTEST_ENTITY=newEntityModelLayer(Identifier.of(FabricDocsReference.MOD_ID,"test_entity"),"main");

构造方法中传递两个参数,第一个参数传递了Identifier.of()方法返回的标识符对象,其中提供模组Id和实体模型层标识符的路径test_entity,第二个参数传递一个字符串,代表实体模型层的名称main

1.2编写实体渲染状态类

实体渲染状态类是1.21.4版本中新增的用于为渲染器提供当前实体渲染状态的类,也是实体渲染器类中需要继承的类。


生物实体渲染状态类LivingEntityRenderState

LivingEntityRenderState类用于捕获实体渲染前的每一帧供实体渲染器读取。在创建指定实体的渲染状态类时需要继承此类。此版本以前的其他版本不需要用到此API。

类中仅声明诸多简单的变量,代表实体渲染的状态属性。


entity目录中创建TestEntityRenderState类,使其继承LivingEntityRenderState类;

publicclassTestEntityRenderStateextendsLivingEntityRenderState{}

测试生物(test_entity)不需要任何用于存储渲染状态的变量,类体可以为空。不过,创建实体渲染状态类是必要的,因为实体模型类和实体渲染器类中会用到此类。

1.3导入实体模型类

实体模型类是决定实体外观的核心类。一般需要提前通过Blockbench制作实体模型,然后导出为Java文件,稍作修改后在此处使用。


实体模型类EntityModel<T extends EntityRenderState>

EntityModel类用于定义实体的几何形状与动画,存储了实体形状外观与动画的核心数据。其泛型通常为实体渲染状态类。一般,实体模型类需要继承此类以完成实体模型的创建。

继承抽象类EntityModel的类需要实现其中的setAngles()方法:

publicvoidsetAngles(T state){this.resetTransforms();}

在指定的实体模型类中此方法将被重写,用于定义实体的动画;

纹理模型数据类TexturedModelData

TexturedModelData类是由Blockbench生成的Java代码中使用到的API,用于存储有纹理的实体模型数据供实体模型注册时使用

其构造方法已被私有化,因此,需要调用静态方法of()来创建此类的对象:

publicstaticTexturedModelDataof(ModelData partData,int textureWidth,int textureHeight){returnnewTexturedModelData(partData,newTextureDimensions(textureWidth, textureHeight));}

其中需要传递三个参数:

  • ModelData partData:模型数据对象;
  • int textureWidth:纹理宽度;
  • int textureHeight:纹理高度;

可以看到方法中调用了构造方法,其中传递了模型数据对象和TextureDimensions类的构造方法;

纹理尺寸类TextureDimensions

TextureDimensions类用于定义实体模型纹理图像的尺寸,可以存储纹理的宽度和高度。在TexturedModelData类的构造方法中调用了此类的构造方法,用于确定纹理图像的尺寸。

模型数据类ModelData和模型组件数据类ModelPartData

ModelData类用于存储实体所有部位的数据,属于模型的根容器。ModelPartData类用于存储实体单个部位的数据,包括几何模型和位置等数据。这些API均被Blockbench生成的代码中使用,用于将Blockbench中编辑好的实体模型在游戏中渲染出来。

想要获取ModelData的对象,可以直接调用ModelData类的无参构造方法。想要获取ModelPartData的对象则需要调用ModelData对象的getRoot()方法:

publicModelPartDatagetRoot(){returnthis.data;}

用于获取当前模型数据对象的根容器;

调用ModelPartData对象的addChild()方法,可以在根容器中添加实体各部位的模型数据:

publicModelPartDataaddChild(String name,ModelPartBuilder builder,ModelTransform rotationData){ModelPartData modelPartData =newModelPartData(builder.build(), rotationData);returnthis.addChild(name, modelPartData);}

一般,这些方法由Blockbench生成,无需手动编写。


1.准备好已经导出的实体模型Java类;

在这里插入图片描述


2.在entity目录中创建TestModel类,将代码粘贴到此处。在类头中修改类名为TestModel并使其继承EntityModel<TestEntityRenderState>TestEntityRenderState是之前创建好的实体渲染状态类;

publicclassTestModelextendsEntityModel<TestEntityRenderState>{publicTestModel(ModelPart root){super(root);}publicstaticTexturedModelDatagetTexturedModelData(){ModelData modelData =newModelData();ModelPartData modelPartData = modelData.getRoot(); modelPartData.addChild("head",ModelPartBuilder.create().uv(0,0).cuboid(-7.0F,-8.0F,-2.0F,8.0F,8.0F,8.0F,newDilation(0.0F)),ModelTransform.pivot(3.0F,0.0F,-2.0F)); modelPartData.addChild("body",ModelPartBuilder.create().uv(0,16).cuboid(-7.0F,-2.0F,-2.0F,8.0F,12.0F,4.0F,newDilation(0.0F)),ModelTransform.pivot(3.0F,2.0F,0.0F)); modelPartData.addChild("right_arm",ModelPartBuilder.create().uv(24,16).cuboid(-3.0F,-2.0F,-2.0F,4.0F,12.0F,4.0F,newDilation(0.0F)),ModelTransform.pivot(-5.0F,2.0F,0.0F)); modelPartData.addChild("left_arm",ModelPartBuilder.create().uv(0,32).cuboid(-3.0F,-2.0F,-2.0F,4.0F,12.0F,4.0F,newDilation(0.0F)),ModelTransform.pivot(7.0F,2.0F,0.0F)); modelPartData.addChild("right_leg",ModelPartBuilder.create().uv(16,32).cuboid(-3.0F,-2.0F,-2.0F,4.0F,12.0F,4.0F,newDilation(0.0F)),ModelTransform.pivot(-1.0F,14.0F,0.0F)); modelPartData.addChild("left_leg",ModelPartBuilder.create().uv(32,0).cuboid(-3.0F,-2.0F,-2.0F,4.0F,12.0F,4.0F,newDilation(0.0F)),ModelTransform.pivot(3.0F,14.0F,0.0F));returnTexturedModelData.of(modelData,64,64);}@OverridepublicvoidsetAngles(TestEntityRenderState state){}}

类中只需保留三个方法:

  • 构造方法:其中需要调用其超类的构造方法;
  • getTexturedModelData():核心方法,用于将模型数据打包为TexturedModelData对象,供注册实体模型层时使用;
  • setAngles():用于为实体添加动画,在下文将展开讲解;

其他内容均可以删除。部分生成的代码可能与当前版本使用的API版本不相符,部分方法的参数列表需手动修改。

1.4注册实体模型层

注册实体模型层的准备工作已经完毕,可以在客户端入口点类中开始注册。


实体模型层注册类EntityModelLayerRegistry

EntityModelLayerRegistry类是专门用于注册实体模型层的工具类,其中的静态方法registerModelLayer()是注册实体模型层的唯一方法:

publicstaticvoidregisterModelLayer(EntityModelLayer modelLayer,TexturedModelDataProvider provider){...EntityModelLayersAccessor.getLayers().add(modelLayer);}

部分方法体已省略,需要传递两个参数:

  • EntityModelLayer modelLayer:实体模型层对象;
  • TexturedModelDataProvider provider:纹理模型数据提供器对象;

纹理模型数据提供器函数式接口TexturedModelDataProvider

TexturedModelDataProvider接口在EntityModelLayerRegistry内部声明,用于接收纹理模型数据对象。接口被@FunctionalInterface修饰,代表其中方法的返回值可以通过表达式传递;

@FunctionalInterfacepublicinterfaceTexturedModelDataProvider{TexturedModelDatacreateModelData();}

其对象出现在EntityModelLayerRegistry类静态方法registerModelLayer()的参数列表中,用于注册实体模型层。


在客户端入口点类的onInitializeClient()方法中直接调用registerModelLayer()方法,完成实体模型层的注册;

@OverridepublicvoidonInitializeClient(){EntityModelLayerRegistry.registerModelLayer(ModModelLayers.TEST_ENTITY,TestModel::getTexturedModelData);}

其中分别传递了实体模型层对象TEST_ENTITY以及TestModel类中的getTexturedModelData()方法的表达式。

第二节——注册实体及其模型渲染器

实体及其模型渲染器的注册大致分为创建实体注册键静态常量(2.1)、编写实体类(2.2)、注册实体(2.3)、编写实体模型渲染器类(2.4) 以及注册实体模型渲染器(2.5) 五个步骤。

2.1创建实体注册键静态常量

我们需要创建实体注册类,在其中声明实体注册键常量供注册实体时使用。


实体类型类EntityType和实体类型构造器内部类EntityType.Builder

EntityType类是Minecraft中所有实体的唯一标识符和类型定义,在实体注册过程和实体类中广泛使用,其对象在注册实体和实体类构造方法中频繁出现。EntityType.Builder内部类声明在EntityType类内部,是专门用于构建EntityType对象的内部类,也同样是注册实体过程中必须用到的类之一。

内部类EntityType.Builder的构造方法已被私有化,想创建其对象需要调用静态方法create()

publicstatic<TextendsEntity>EntityType.Builder<T>create(EntityType.EntityFactory<T> factory,SpawnGroup spawnGroup){returnnewEntityType.Builder<>(factory, spawnGroup);}

其中传递两个参数:

  • EntityType.EntityFactory<T> factoryEntityType.EntityFactory<T>类型代表需要传递一个能够返回EntityType对象的表达式;
  • SpawnGroup spawnGroup:生成组枚举常量;

完成后,还需要调用其对象的build()方法完成EntityType对象的构造;

publicEntityType<T>build(RegistryKey<EntityType<?>> registryKey){if(this.saveable){Util.getChoiceType(TypeReferences.ENTITY_TREE, registryKey.getValue().toString());}returnnewEntityType<>(...);}

方法支持链式调用,其中传递一个指定生物EntityType类型的注册键对象;

生成组枚举类SpawnGroup

枚举类SpawnGroup用于对实体进行分类,在注册实体时会使用到其中的枚举常量,这些常量包括:

  • MONSTER:怪物;
  • CREATURE:动物;
  • AMBIENT:环境生物;
  • AXOLOTLS:美西螈;
  • UNDERGROUND_WATER_CREATURE:地下水生生物;
  • WATER_CREATURE:水生生物;
  • WATER_AMBIENT:水下环境生物;
  • MISC:其他;

这些常量也用于控制实体在生物群系的生成。


1.在客户端入口点类所在目录直接创建实体注册类ModEntities

在这里插入图片描述


2.声明类型为RegistryKey<EntityType<?>>的注册键静态常量;

publicstaticfinalRegistryKey<EntityType<?>>TEST_ENTITY_REGISTRY_KEY=RegistryKey.of(RegistryKeys.ENTITY_TYPE,Identifier.of(FabricDocsReference.MOD_ID,"entity_test"));

调用RegistryKey.of()方法,其中分别传递注册键类型为实体类型RegistryKeys.ENTITY_TYPE,以及Identifier.of()方法返回的由模组Id与路径entity_test组成的标识符对象。

关于RegistryKey.of()方法的详细用法请参考我的世界Java版1.21.4的Fabric模组开发教程(五)创建高级物品:盔甲

关于Identifier类的详细用法说明请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品

2.2编写实体类

现在,我们开始为测试生物(test_entity)编写实体类。实体类用于定义实体属性与具体行为,是创建实体过程中的关键类。一般,实体类需要继承已有的实体父类来确定实体的大致类型。


动物实体类AnimalEntity

AnimalEntity类是Minecraft中的动物实体类,也是所有被动/友好动物的基类。游戏中所有带有动物性质的实体都继承了此类,继承此类通常至少要重写以下两个方法:

  • isBreedingItem(ItemStack stack):用于判断给定的物品是否能触发该动物的繁殖行为,一般直接返回false
  • createChild(ServerWorld world, PassiveEntity entity):用于创建此实体的一个幼年实体,一般返回null

1.在entity/custom目录中创建TestEntity类,作为测试生物的实体类;

在这里插入图片描述


2.使其继承AnimalEntity类并重写相关方法,使测试生物具有动物实体的性质与行为;

publicclassTestEntityextendsAnimalEntity{publicTestEntity(EntityType<?extendsAnimalEntity> entityType,World world){super(entityType, world);}@OverridepublicbooleanisBreedingItem(ItemStack stack){returnfalse;}@Overridepublic@NullablePassiveEntitycreateChild(ServerWorld world,PassiveEntity entity){returnnull;}}

2.3注册实体

现在,我们可以通过实体类将测试生物(test_entity)在游戏注册表中注册,这些代码需要添加到实体注册类中,即ModEntities类;

声明静态常量TEST_ENTITY并调用Register.registry()方法。关于Register.registry()方法的详细用法说明,请参考我的世界Java版1.21.4的Fabric模组开发教程(二)创建物品

publicstaticfinalEntityType<TestEntity>TEST_ENTITY=Registry.register(Registries.ENTITY_TYPE,Identifier.of(FabricDocsReference.MOD_ID,"test_entity"),EntityType.Builder.create(TestEntity::new,SpawnGroup.AMBIENT).build(TEST_ENTITY_REGISTRY_KEY));

方法中传递三个参数,第一个是注册实体的固定写法Registries.ENTITY_TYPE,第二个参数传递Identifier.of()方法返回的由模组Id和路径组成的标识符对象,第三个参数中首先调用内部类EntityType.Builder的静态方法create()创建实体类型构造器对象,其中传递实体类构造方法的表达式TestEntity::new以及生成组枚举常量SpawnGroup.AMBIENT,然后调用build()方法完成EntityType对象的构造,其中传递实体注册键对象。

2.4编写实体模型渲染器类

为了使测试生物(test_entity)在世界中正常渲染,还需要编写实体模型渲染器类。


生物实体渲染器类MobEntityRenderer

MobEntityRenderer是Minecraft中所有可移动生物的基础渲染器类,用于提供在游戏中渲染实体所需的标准框架和通用功能。一般创建实体模型渲染器类需要先继承此类。

MobEntityRenderer类的全类名为:

publicabstractclassMobEntityRenderer<TextendsMobEntity,SextendsLivingEntityRenderState,MextendsEntityModel<?superS>>extendsLivingEntityRenderer<T,S,M>{...}

其中的泛型包括:

  • T extends MobEntity:实体类,需要继承MobEntity类及其子类;
  • S extends LivingEntityRenderState:实体渲染状态类,需要继承LivingEntityRenderState类;
  • M extends EntityModel<? super S>:实体模型类,需要继承EntityModel<? super S>类,这里的<? super S>代表实体渲染状态类;

其构造方法将在继承此类的实体渲染器类中被调用:

publicMobEntityRenderer(EntityRendererFactory.Context context,M entityModel,float f){super(context, entityModel, f);}

需要传递三个参数:

  • EntityRendererFactory.Context context:实体渲染器工厂上下文对象;
  • M entityModel:实体模型类对象,需要调用实体模型类的构造方法;
  • float f:实体阴影大小,单位为方块;

实体渲染器工厂上下文内部类EntityRendererFactory.Context

EntityRendererFactory.Context类声明在EntityRendererFactory类内部,属于实体渲染期间的工具类,包含了渲染一个实体所需的所有依赖和资源。其对象在实体渲染器类中构造方法的参数列表中出现。

一般,最常用的方法为getPart(),用于通过模型层获取模型部件;

publicModelPartgetPart(EntityModelLayer layer){returnthis.entityModels.getModelPart(layer);}

方法需要传递一个实体模型层对象作为参数。


继承了MobEntityRenderer类的实体渲染器类中至少要添加以下内容:

  • 实体展开图(UV图)的标识符对象:UV图应当提前导出并存储在服务器模块的textures/entity目录中,用于渲染实体各部件上的贴图;
  • 构造方法:其中调用其超类的构造方法;
  • createRenderState():方法重写自超类,用于返回实体渲染状态对象;
  • getTexture():方法重写自超类,用于获取UV图的标识符对象;

1.创建实体渲染器类TestModelRenderer并使其继承MobEntityRenderer

publicclassTestModelRendererextendsMobEntityRenderer<TestEntity,TestEntityRenderState,TestModel>{}

泛型中要依次添加实体类TestEntity、实体渲染状态类TestEntityRenderState以及实体模型类TestModel

2.声明名为TEXTURE的实体展开图(UV图)标识符对象静态常量,类型为Identifier

privatestaticfinalIdentifierTEXTURE=Identifier.of(FabricDocsReference.MOD_ID,"textures/entity/test.png");

调用Identifier.of()方法对其初始化,其中分别传递模组Id和贴图在项目中的路径,指定贴图的位置;

3.声明构造方法,方法体中调用其父类的构造方法;

publicTestModelRenderer(EntityRendererFactory.Context context){super(context,newTestModel(context.getPart(ModModelLayers.TEST_ENTITY)),0.5f);}

其中首先传递实体渲染器工厂上下文对象context,然后调用实体模型类的构造方法,来获取实体模型对象,构造方法中调用context.getPart()方法,其中继续传递实体模型层对象来获取模型部件对象,最后设置实体阴影为0.5个方块的大小;

4.重写createRenderState()方法,其中直接返回实体渲染状态对象;

@OverridepublicTestEntityRenderStatecreateRenderState(){returnnewTestEntityRenderState();}

5.重写getTexture()方法,其中返回实体展开图(UV图)标识符对象TEXTURE

@OverridepublicIdentifiergetTexture(TestEntityRenderState state){returnTEXTURE;}

2.5注册实体模型渲染器

最后,还要在客户端入口点类中注册测试生物(test_entity)的实体模型渲染器。


实体渲染器注册类EntityRendererRegistry

EntityRendererRegistry是专门用于注册实体模型渲染器的工具类,是实体创建过程中一定会用到的类。

类中只有一个静态方法register(),用于注册实体模型渲染器:

publicstatic<EextendsEntity>voidregister(EntityType<?extendsE> entityType,EntityRendererFactory<E> entityRendererFactory){EntityRendererRegistryImpl.register(entityType, entityRendererFactory);}

其中需要传递两个参数:

  • EntityType<? extends E> entityType:实体类型对象;
  • EntityRendererFactory<E> entityRendererFactory:此处需要传递一个返回实体模型渲染器对象的表达式;

在客户端入口点类的onInitializeClient()方法中直接注册实体模型渲染器;

EntityRendererRegistry.register(ModEntities.TEST_ENTITY,TestModelRenderer::new);

调用EntityRendererRegistry类的静态方法register()完成实体模型渲染器的注册,其中分别传递实体类型对象ModEntities.TEST_ENTITY以及实体模型渲染器类构造方法的表达式TestModelRenderer::new

本章小结

本章详细阐述了注册实体第一节和第二节的所有工作,完成了实体模型层、实体渲染器以及实体本身的注册。由于篇幅原因,第三节和第四节的内容将在下一章展开。本章内容难度较大且操作繁琐,需要开发者有一定的耐心。在下一章,我们将定义实体属性,完成创建生物的最后一步,然后启动游戏开始测试生物在游戏中的表现,并进行生物创建完毕的善后工作。感谢各位的阅读,有兴趣可以订阅此专栏!

Read more

【C++ 进阶】继承(上):解锁代码复用的核心密码,体会代码复用的魅力!

【C++ 进阶】继承(上):解锁代码复用的核心密码,体会代码复用的魅力!

前言:C++的三大核心特性是封装、继承和多态。在前文中,我们已经通过类和对象讲解了封装特性。接下来,本文将深入探讨C++继承机制的奥秘。 🌟 专注用图文结合拆解难点+代码落地知识,让技术学习从「难懂」变“一看就会”! 🏠 个人主页 :MSTcheng · ZEEKLOG 💻 代码仓库 :MSTcheng · Gitee📚 精选专栏 :📖 :《C语言》🧩 :《数据结构》💡 :《C++由浅入深》💬 座右铭 :“路虽远行则将至,事虽难做则必成!” 文章目录 * 一、继承的概念及定义 * 1.1继承的概念 * 1.2继承的定义 * 1.3继承方式与访问方式的组合 * 1.4继承类模板 * 二、基类和派生类对象的赋值转换 * 三、继承中的作用域 * 3.1隐藏规则 * 3.2继承作用域的两道笔试题 * 四、总结

By Ne0inhk
C++波澜壮阔40年|类和对象篇:拷贝构造与赋值重载的演进与实现

C++波澜壮阔40年|类和对象篇:拷贝构造与赋值重载的演进与实现

🔥@雾忱星: 个人主页 👀专栏:《数据结构与算法入门指南》、《C++学习之旅》 💪学习阶段:C/C++、数据结构与算法 ⏳“人理解迭代,神理解递归。” 文章目录 * 引言 * 一、拷贝构造函数 * 1.1 解析:拷贝构造特点 * 1.2 关键:拷贝构造的调用 * 二、赋值运算符重载 * 2.1 铺垫:运算符重载特点 * 2.1.1 核心:理解运算符重载 * 2.2 进阶:赋值运算符重载特点 * 2.2 核心:理解赋值运算符重载 * 总结 引言 在C++面向对象编程中,对象的复制操作无处不在。无论是函数传参、返回值传递,

By Ne0inhk
【C++:智能指针】没有垃圾回收?智能指针来也!破解C++内存泄漏:智能指针原理、循环引用与线程安全详解

【C++:智能指针】没有垃圾回收?智能指针来也!破解C++内存泄漏:智能指针原理、循环引用与线程安全详解

🎬 个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》《数据结构与算法》《C/C++干货分享&学习过程记录》 《Linux操作系统编程详解》《笔试/面试常见算法:从基础到进阶》《Python干货分享》 ⭐️为天地立心,为生民立命,为往圣继绝学,为万世开太平 🎬 艾莉丝的简介: 🎬 艾莉丝的C++专栏简介: 文章目录 * C++学习阶段的三个参考文档 * 1 ~> 前言:智能指针的使用场景 * 2 ~> RAII和智能指针的设计思路 * 2.1 理论:RAII * 2.2 最佳实践 * 2.3 实践RAII:核心思想 * 3 ~> C++标准库智能指针的使用 * 3.1 理论

By Ne0inhk
C++ 面试题常用总结 详解(满足c++ 岗位必备,不定时更新)

C++ 面试题常用总结 详解(满足c++ 岗位必备,不定时更新)

📚 本文主要总结了一些常见的C++面试题,主要涉及到语法基础、STL标准库、内存相关、类相关和其他辅助技能,掌握这些内容,基本上就满足C++的岗位技能(红色标记为重点内容),欢迎大家前来学习指正,会不定期去更新面试内容。  Hi~!欢迎来到碧波空间,平时喜欢用博客记录学习的点滴,欢迎大家前来指正,欢迎欢迎~~ ✨✨ 主页:碧波 📚 📚 专栏:C++ 系列文章 目录 一、C ++ 语法基础 🔥 谈谈变量的使用和生命周期,声明和初始化 🔥 谈谈C++的命名空间的作用 🔥  include " " 和 <> 的区别 🔥 指针是什么? 🔥 什么是指针数组和数组指针 🔥 引用是什么? 🔥 指针和引用的区别 🔥 什么是函数指针和指针函数以及区别 🔥 什么是常量指针和指针常量以及区别 🔥 智能指针的本质是什么以及实现原理 🔥 weak_ptr 是否有计数方式,在那分配空间? 🔥 类型强制转换有哪几种? 🔥 函数参数传递时,

By Ne0inhk