C++基础#20:C++中的动态强制dynamic_cast

dynamic_cast介绍 首先说到c++常用的四中转换类型,我们都很清楚,分别是下面四中   1 const_cast  const_cast<目标类型>(标识符):目标类型只能是指针或者引用2 static_cast 类似C风格的强制转换,进行无条件转换,静态类型转换: 1)基类和子类之间的转换:其中子类指针转换为父类指针是安全的,但父类指针转换为子类指针是不安全的(基类和子类之间的动态类型转换建议用dynamic_cast)。 2)基本数据类型转换,enum,struct,int,cha... 阅读详情
AI摘要

本文深入讲解C++中dynamic_cast的原理与应用,重点阐述其作为运行时类型识别(RTTI)机制的核心作用。内容涵盖dynamic_cast的使用前提(必须含虚函数)、向上/向下转换规则、虚继承与非虚继承场景下的行为差异,并通过多组示例代码说明安全转换条件及常见错误。同时指出其在Android NDK等真实项目源码中的实际应用。

简介:

C++中提供了动态强制(dynamic_cast),是一种运行时类型识别机制,可以从一个虚的基类强制到一个派生类。我们常常需要知道,在运行过程中,我们真正在使用的是哪个类的对象,这时,可以明确地使用dynamic_cast来得到运行时类型的信息。

 数据类型转换系列文章:

C++中的动态强制dynamic_cast

C++中的RTTI机制之typeid

C++中的静态强制static_cast

C++中的reinterpret_cast数据类型转换

C++中的const_cast数据类型转换

 dynamic_cast注意事项以及示例代码:

注意事项:

虚基类(或称抽象类)可以使用dynamic_cast,但是,非虚基类不可以。

在dynamic_cast被设计之前,C++无法实现从一个虚基类到派生类的强制转换。dynamic_cast就是为解决虚基类到派生类的转换而设计的。

示例代码:

示例代码1: 子类--->父类(虚基类)

#include <stdio.h>
#include <stdlib.h>

//美术家
class Artist {
    public:
        virtual void draw() {printf("Artist draw\n");}
};

//音乐家
class Musician {
	public:
};

//教师
class Teacher {
    public:
        virtual void teachStu() {printf("Teacher teachStu\n");}
};

//即是美术,又是音乐家,又是教师的人
class Amt: public virtual Artist,public virtual Musician,public Teacher {
	public:

};

void test1() {

	Amt *p1 = new Amt();
	p1->draw();
	p1->teachStu();

	printf("\ndynamic_cast test:\n");

	Artist *a1 =  dynamic_cast<Artist*>(p1);
	//Artist *a1 =  p1; //向上转换,C++总是能够正确识别。即将派生类的指针赋值给基类指针。

	a1->draw();     //success: 打印Artist draw
	//a1->teachStu(); //error: no member named 'teachStu' in 'Artist'

}

int main() {
	test1();

	return 0;

}

说明:

1)继承关系:Amt 继承自Artist,Musician,Teacher三个类;

2)语意:Artist美术家,Musician音乐家,Teacher教师。

Amt类:定义一个类,它的特点是:既是美术家,又是音乐家,也是教师。

上面的代码,运行结果如下:

Artist draw

Teacher teachStu

dynamic_cast test:

Artist draw

分析:

下面两条语句均正确,都能由子类Amt转化为父类Artist,并且调用父类Artist的成员函数成功。

Artist *a1 =  dynamic_cast<Artist*>(p1); 等价于

Artist *a1 =  p1; 

a1->draw();     //success

可见,向上转换,无论是否用dynamic_cast,C++总是能够正确识别,即将派生类的指针赋值给基类指针。

示例代码2:  父类(虚基类)--->子类,采用虚继承的方式:

对于上面的类,再看如下代码:

void test1() {

	Amt *p1 = new Amt();
	
	printf("\ndynamic_cast test:\n");

	Artist *a1 = p1; //success
	//Amt *p2 = (Amt*)a1; //error: cannot cast 'Artist *' to 'Amt *' via virtual base 'Artist'
	Amt *p3 = dynamic_cast<Amt*>(a1);//success:加了dynamic_cast,进行强转
}

分析:

 1)   //Amt *p2 = (Amt*)a1; //error: cannot cast 'Artist *' to 'Amt *' via virtual base 'Artist',
明确说明,无法直接用(T*)b的形式去进行由父类指针到派生类指针的转换;

2) Amt *p3 = dynamic_cast<Amt*>(a1);//success:加了dynamic_cast,进行强转。

由父类指针到派生类指针的转换通过dynamic_cast完成。
重点来了,为什么使用了dynamic_cast,基类指针a1就能转换为派生类指针p3呢?
这就是RTTI机制,
RTTI:Run Time Type Identification,即通过运行时类型识别。程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型。

以上案例中,各个实例和class总结如下:

a1: Artist

m1:Musician

t1:Teacher

p1:Amt

Amt: 继承自Artist,Musician,Teacher。

在这个内存模型中:

每个类都会在内存中保存一份类型信息,编译器会将存在继承关系的类的类型信息使用指针“连接”起来,从而形成一个继承链(Inheritance Chain)。

dynamic_cast使用注意事项:

1)查找规则:当使用 dynamic_cast 对指针进行类型转换时,会先找到该指针指向的对象,再根据对象找到当前类(指针指向的对象所属的类)的类型信息,并从此节点开始沿着继承链向上遍历(注意是向上),如果找到了要转化的目标类型,那么说明这种转换是安全的,就能够转换成功,如果没有找到要转换的目标类型,那么说明这种转换存在较大的风险,就不能转换。

2)作用对象:注意dynamic_cast转换符只能用于含有虚函数的类。

现在,用RTTI来解释test1()函数中的代码:

p1是派生类指针,a1是基类指针,根据RTTI机制,从p1所指向的类Amt类向上找,能找到a1所指的类Artist类,所以,dynamic_cast转换是合法的。

示例代码3:  父类(非虚基类)--->子类,采用虚继承的方式:
void test3() {

	Amt *p1 = new Amt();
	
	printf("\ndynamic_cast test:\n");

	Musician *m1 = p1; //success
	Amt *p2 = (Amt*)m1; //cannot cast 'Musician *' to 'Amt *' via virtual base 'Musician'
	Amt *p3 = dynamic_cast<Amt*>(m1);//error: 'Musician' is not polymorphic

}

 分析:

根据dynamic_cast使用注意事项中的“dynamic_cast转换符只能用于含有虚函数的类(虚基类

)”, Musician是非虚基类,所以,无法进行强制dynamic_cast转换。

示例代码4:  父类(虚基类)--->子类,采用非虚继承的方式:
void test4() {

	Amt *p1 = new Amt();
	
	printf("\ndynamic_cast test:\n");

	Teacher *t1 = p1; //success
	Amt *p2 = (Amt*)t1;                //success,继承自Teacher,采用非虚继承的方式(不使用virtual),所以ok。
	Amt *p3 = dynamic_cast<Amt*>(t1);  //success:加了dynamic_cast,进行强转

}

 分析:

1)对于

Amt *p2 = (Amt*)t1; 

Amt继承自Teacher,而采用非虚继承的方式,成功,因为采用的是非虚继承;

2)对于

Amt *p3 = dynamic_cast<Amt*>(t1); 

加了dynamic_cast,进行强转,成功,因为Teacher是虚基类,而且符合RTTI规则。

dynamic_cast源码举例:

在Android源码中,可以查看到很多dynamic_cast的实现,来看其中一例:

代码位置:

/ndk/sources/cxx-stl/gabi++/src/dynamic_cast.cc

部分代码摘抄:

(从函数名字就可以看出,这个函数的作用是:把基类转换成派生类)

// based-to-derive cast in the general case.

  void
  base_to_derived_cast(const void *object,
                       const abi::__class_type_info *type,
                       cast_context* context)
  {
    const void* saved_dst_object = context->dst_object;
    bool is_dst_type = *type == *context->dst_type;
    if (is_dst_type)
      context->dst_object = object;

    if (object == context->object
        && context->dst_object != NULL
        && *type == *context->src_type)
      {
        if (context->result == NULL)
          context->result = context->dst_object;
        else if (context->result != context->dst_object)
          context->result = ambiguous_object;
        context->dst_object = saved_dst_object;
        return;
      }

    switch(type->code())
      {
      case abi::__class_type_info::CLASS_TYPE_INFO_CODE:
        // This isn't not the class you're looking for.
        break;

      case abi::__class_type_info::SI_CLASS_TYPE_INFO_CODE:
        // derived type has a single public base at offset 0.
        {
          const abi::__si_class_type_info* ti =
            static_cast<const abi::__si_class_type_info*>(type);
          base_to_derived_cast(object, ti->__base_type, context);
          break;
        }

      case abi::__class_type_info::VMI_CLASS_TYPE_INFO_CODE:
        {
          const void* vtable = get_vtable(object);
          const abi::__vmi_class_type_info* ti =
            static_cast<const abi::__vmi_class_type_info*>(type);

          // Look at all direct bases.
          for (unsigned i = 0; i < ti->__base_count; ++i)
            {
              if (!ti->__base_info[i].is_public())
                continue;

              const void *subobject =
                get_subobject(object, vtable, &ti->__base_info[i]);
              base_to_derived_cast(subobject, ti->__base_info[i].__base_type,
                                   context);

              // FIXME: Use flags in base_info to optimize search.
              if (context->result == ambiguous_object)
                break;
            }
          break;
        }

      default:
        assert(0);
      }
     context->dst_object = saved_dst_object;
  }
} // namespace


C++结构体强制类型转换:内存布局、对齐与安全实践详解 强制类型转换是C++中连接高级抽象与底层内存操作的核心技术,它允许开发者重新解释内存数据的类型。其原理基于编译器对内存布局的直接操作,绕过类型系统的静态检查。这项技术的核心价值在于实现高性能的底层系统编程、硬件交互、网络协议解析以及与C语言库的无缝对接。在应用场景上,它常见于序列化/反序列化、泛型容器实现和跨语言接口调用。然而,不当使用会引发严格别名规则违规和内存对齐问题,导致未定义行为。本文聚焦于结构体场景,深入解析reinterpret_cast等转换方式的安全边界,强调标准布局类型验证和std::me 阅读详情

相关推荐

C++(03):dynamic_cast

dynamic_cast主要用于有继承关系的多态类(基类必须有虚函数)的指针或引用之间的转换。1.通过dynamic_cast,将派生类指针转换为基类指针(上行转换),这个操作与static_cast的效果是一样的。2.通过dynamic_cast,将基类指针转换为派生类指针(下行转换),dynamic_cast具有类型检查的功能,比static_cast更安全(如果转换的是指针,失败时会返回空指针;如果转换的是引用,会抛出std::bad_cast异常)...

风静如云的博客 5205

C++新特性08_强制转换dynamic_cast(具有虚函数基类的父转子的时候会存在越界问题,因此必须使用dynamic_cast在运行时检测转换是否安全、其本质是采用RTTI:运行时类型检测技术)

dynamic_cast用于具有虚函数的基类与派生类之间的指针或引用的转换。 使用的情况: (1)基类必须具备虚函数 原因:dynamic_cast是运行时类型检查,需要运行时类型信息(RTTI),而这个信息是存储与类的虚函数表关系紧密,只有一个类定义了虚函数,才会有虚函数表。 (2)运行时检查,转型不成功则返回一个空指针 (3)非必要不要使用DYNAMIC_CAST,有额外的函数开销 1.父类转子类情况下的越界问题: #include <iostream> #include <stri

分享学习成长历程,Winter is coming! 3398

C++ 中dynamic_cast使用详解和实战示例

当不确定指针实际指向哪个派生类时,用 dynamic_cast。当能确定类型时,用 static_cast。基类必须有虚函数。失败返回 nullptr。

qq_36812406的博客 1020

C++类型转换操作符 dynamic_cast

dynamic_cast 顾名思义是支持动态的类型转换,即支持运行时识别指针或引用所指向的对象。 dynamic_cast&lt;&gt;用于C++类继承多态间的转换,分为: 子类向基类的向上转型(Up Cast) 基类向子类的向下转型(Down Cast) 其中向上转型不需要借助任何特殊的方法,只需用将子类的指针或引用赋给基类的指针或引用即可,dynamic_cast向上转型其总是...

冰殇的博客 2170

基于Java的高校校园点餐系统

本文介绍了一个基于Java技术开发的高校校园点餐系统,该系统以B/S结构为基础,采用MySQL作为数据库,实现了一个高效、便捷的在线点餐平台。系统主要面向三类用户:管理员、用户和食堂工作人员,提供包括用户管理、食堂管理、菜单管理、订单管理等在内的多项功能。通过系统的具体测试,验证了其可行性和有效性,为高校师生提供了一个科学化、系统化的点餐服务。高校校园点餐系统的开发和实现,不仅提高了校园餐饮服务的效率和质量,也为师生提供了一个更加便捷的点餐体验。

a632341031的博客 838

用Arduino和MAX30102做个心率血氧仪,从硬件连线到算法调试全流程避坑

本文详细介绍了如何使用Arduino和MAX30102传感器构建高精度心率血氧仪,涵盖硬件连线、软件配置、信号处理及算法优化全流程。通过实战案例和避坑指南,帮助开发者快速实现临床级精度的健康监测设备,适用于可穿戴设备和医疗健康领域。

weixin_26897585的博客 383

C++基础#24:C++中的const_cast,数据类型转换

C++中的const_cast运算符用于修改类型的const或volatile属性,从而强制消除对象的常量性。使用const_cast去除const限定的目的并不是为了修改它的内容。变量本身的const属性是不能去除的,要想修改变量的值,一般是去除指针(或引用)的const属性,再进行间接修改。

记录和分享程序人生的点点滴滴 3435

C++四种类型转换详解:static_cast、dynamic_cast、const_cast、reinterpret_cast

类型转换是编程中的基础概念,它允许在不同数据类型之间进行转换,以满足数据处理和接口调用的需求。其原理基于内存布局的重新解释或编译器提供的安全检查机制,旨在平衡灵活性与安全性。在C++中,类型转换的技术价值尤为突出,它通过引入四种命名的强制转换操作符,取代了C风格转换的模糊性和危险性,从而提升代码的健壮性和可维护性。这些操作符各有明确的适用场景:static_cast用于相关类型间的编译期转换,dynamic_cast提供运行时多态类型的安全检查,const_cast专门处理常量性修改,而reinterpre

cuemes08808的博客 360

从飞机翼型仿真到燃烧模拟:Fluent多物理场耦合的3种实战策略

本文深入探讨了Fluent在多物理场耦合仿真中的三种实战策略,涵盖可压缩流动与燃烧耦合、湍流模型选择及网格策略,以及顺序耦合、强耦合和混合耦合方法。通过具体案例和工程实践,帮助中高级用户提升仿真精度和效率,适用于航空航天和能源化工等领域。

aa123的博客 994

在线机器学习(OML-AD)应对时序数据概念漂移的异常检测实战

时序数据异常检测是监控系统健康、识别业务风险的核心技术。其基本原理是通过预测模型学习数据的正常模式,并将预测误差作为异常判定的依据。然而,当数据背后的统计规律随时间发生变化,即发生概念漂移时,传统的静态模型会失效,导致误报和漏报激增。在线机器学习技术通过增量学习,使模型能够随每个新数据点实时微调,为预测式异常检测提供了动态适应能力,从而在数据流持续演化的场景下保持检测的鲁棒性。这种将预测与检测无缝衔接的OML-AD框架,尤其适用于工业监控、金融风控等对实时性与资源效率要求高的领域,有效解决了概念漂移这一核心

weixin_29889665的博客 530

类型转换操作符:static_cast, dynamic_cast, const_cast, reinterpret_cast.

呵呵,今天来好好看看着几个转换操作符的用法。以前老是看着眼熟,但是用着手生。今天决定搞定这些个东西。在C语言中类型转换有几种方式:1.      (expression). 在表达式外边加括号,由编译器来决定怎么改变。2.      new_type(expression). 强制类型括号住表达式。3.      (new_type)expression. 括号住强制类型。4.

每天进步一点点... 5406

Qt EGLFS 图形后端详解

EGLFS (EGL Full Screen) 是Qt框架在嵌入式Linux系统中的高性能图形显示后端,它提供了直接基于EGL和OpenGL ES的硬件加速渲染解决方案。

浩瀚之水的专栏 513

C++强制类型转换

文章目录C语言的强制类型转换C++ 的强制类型转换const_castdynamic_cast----RTTI运行时类型识别static_castreinterpret_cast C语言的强制类型转换 先看个笔试选择常考题,看下面代码,写出运行结果: #include&amp;amp;amp;amp;amp;lt;iostream&amp;amp;amp;amp;amp;gt; using namespace std; int main() { const int a = ...

假正经Leo先生 1693

【天气雷达】双偏振产品-差分反射率ZDR详解

双偏振产品-差分反射率ZDR详解。

珞瑜的博客 5408

解锁机器人逆运动学算法:从理论到实战

机器人逆运动学,简单来说,就是已知机器人末端执行器(如机械臂的手部、工具等)期望达到的位置和姿态,求解机器人各个关节需要达到的角度或位移的过程。在机器人的实际应用场景中,逆运动学起着不可或缺的作用。以工业制造中的焊接机器人为例,为了完成复杂的焊接任务,焊接头(末端执行器)需要精准地到达工件上的各个焊接点,并保持合适的姿态以确保焊接质量。这时,逆运动学算法就根据焊接点的三维坐标以及焊接头应有的姿态(如角度等),计算出机械臂各个关节的转动角度,从而控制机械臂带动焊接头准确地运动到目标位置。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 2052

常规投放vs. static_cast与dynamic_cast [重复]

这个问题已经在这里有了答案: 什么时候应该使用static_cast,dynamic_cast,const_cast和reinterpret_cast? 8个答案

p15097962069的博客 204

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

C++ RTTI详解

C++ RTTI详解1、RTTI简介2、typeid详解2.1、type_info2.2、typeid识别静态类型2.3、typeid识别动态类型2.4、typeid实现原理3、dynamic_cast详解4、总结 1、RTTI简介 RTTI(Runtime Type Identification)是“运行时类型识别”的意思。C++引入这个机制是为了让程序在运行时能根据基类的指针或引用来获得该指针或引用所指的对象的实际类型。但是现在RTTI的类型识别已经不限于此了,它还能通过typeid操作符识别出所有的基

游戏行业资深搬砖人员 2万+

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain&#39;s apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath(&#39;DeepLearnToolbox&#39;));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand(&#39;state&#39;,0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W&#39;); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand(&#39;state&#39;,0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = &#39;sigm&#39;;%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, &#39;Too big error&#39;);```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand(&#39;state&#39;,0)sae = saesetup([784 100]);sae.ae{1}.activation_function = &#39;sigm&#39;;sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)&#39;)% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = &#39;sigm&#39;;nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, &#39;Too big error&#39;);```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x&#39;,28,28,60000))/255;test_x = double(reshape(test_x&#39;,28,28,10000))/255;train_y = double(train_y&#39;);test_y = double(test_y&#39;);%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you&#39;ll get around 1.2% errorrand(&#39;state&#39;,0)cnn.layers = { struct(&#39;type&#39;, &#39;i&#39;) %input layer struct(&#39;type&#39;, &#39;c&#39;, &#39;outputmaps&#39;, 6, &#39;kernelsize&#39;, 5) %convolution layer struct(&#39;type&#39;, &#39;s&#39;, &#39;scale&#39;, 2) %sub sampling layer struct(&#39;type&#39;, &#39;c&#39;, &#39;outputmaps&#39;, 12, &#39;kernelsize&#39;, 5) %convolution layer struct(&#39;type&#39;, &#39;s&#39;, &#39;scale&#39;, 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, &#39;Too big error&#39;);```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, &#39;Too big error&#39;);%% ex2 neural net with L2 weight decayrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex3 neural net with dropoutrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex4 neural net with sigmoid activation functionrand(&#39;state&#39;,0)nn = nnsetup([784 100 10]);nn.activation_function = &#39;sigm&#39;; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex5 plotting functionalityrand(&#39;state&#39;,0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = &#39;softmax&#39;; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand(&#39;state&#39;,0)nn = nnsetup([784 20 10]); nn.output = &#39;softmax&#39;; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, &#39;Too big error&#39;);```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

static_cast、dynamic_cast reinte…

static_cast、dynamic_cast reinterpret_cast和const_ (2009-09-04 10:41:56) te><img title= "static_cast、dynamic_cast reinterpret_cast和const_ - 上帝有罪 - 上帝有罪的博客" alt= "static_cast、dynamic_cast reinterpret_cas

好好工作,好好生活, 592

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【c++】四种类型转换形式

编译时:static_cast(静态转换)const_cast(去常性转换)reinterpret_cast(重新解释转换,直接转换地址)运行时:dynamic_cast(动态转换,运行时类型识别 RTTI)

m0_64014551的博客 1608

类型转换操作符:static_cast, dynamic_cast, const_cast, reinterpret_cast

原地址:http://blog.youkuaiyun.com/callmeback/article/details/4040583 在C语言中类型转换有几种方式: 1.      (expression). 在表达式外边加括号,由编译器来决定怎么改变。 2.      ne

zhaogn 的技术博客 550

c++基础语法

所以c++提供了一个更高效的写法,这个只针对构造函数有效这个冒号 : 引导的语法叫做“成员初始化列表”

weixin_40453090的博客 220

[量化]《C++ 四种类型转换全解析:使用场景、风险与最佳实践》

C++ 提供了 `static_cast`、`dynamic_cast`、`const_cast` 和 `reinterpret_cast` 四种命名的强制类型转换,它们比 C 风格转换更清晰、更可控。它是**唯一**能处理常量性的 C++ 转换。- **无关类型转换**:不能将 `int*` 转成 `float*`(应使用 `reinterpret_cast`)。**核心危险**:对真正定义为 `const` 的对象使用 `const_cast` 并修改,结果是**未定义行为**。

qq_55948352的博客 376

命名的强制类型转换

一旦我们去掉了某个对象的const性质,编译器就不再阻止我们对该对象进行写操作了。然而如果对象是一个常量,再使用const_cast执行写操作就会产生未定义的后果。就算实在无法避免,也应该尽量限制类型转换值的作用域,并且记录对相关类型的所有假定,这样可以减少错误发生的机会。使用reinterpret_cast是非常危险的,reinterpret_cast本质上依赖于机器。要想安全地使用reinterpret_cast必须对涉及的类型和编译器实现转换的过程都非常了解。

mjmald的博客 107
上一篇: 摩托罗拉android产品 MT710
下一篇: Android基础#16:Android利用adb bugreport获取设备运行信息
liranke
博客等级 码龄20年 4939粉丝 594原创
评论 1
成就一亿技术人!
拼手气红包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、付费专栏及课程。

余额充值