C++基本功和 Design Pattern系列 Type Cast, Interface Inheritance VS Implementation Inheritance

C和C++的强制类型转换 C++ 四种强制类型转换 一般来说,我们需要类型转换的场景可以分为如下几种: 整型和浮点型以及不同长度的数据相互转换 一般规则是:占用内存低的向占用内存高的自动转换,而反向则会有转换截断的问题 整型和指针相互转换 当我们试图根据某个成员变量的偏移位计算其在该对象内存空间位置时,就会需要将指针转换为整型进行计算。当计算出该变量的位置后(整型),就需要将其转换为指针类型。 整型和枚举类型相互转换。 这种转换往往发生在数学计算的场景下。因为枚举一般只是用于表意,而实际参与运算的还是整型数据。 指针 阅读详情
许多学过C的朋友一定还记得C语言中的类型转换,例如:

float FloatNum = 1.234;
int IntNum = (int)FloatNum;
// IntNum = 1

这是比较正常的类型转换,稍微危险一点的转换如下:

float FloatNum = 1.234;
float * pFloatPointer = &FloatNum;
int * pIntPointer = (int *)pFloatPointer;
// *pIntPointer 里边就是乱七八糟的东西了

C 的类型转换虽然很方便,但是却带来了更多的问题。比如 C的类型转换可以允许你进行任意类型之间的转换。 非常随意的使用类型转换很容易造成程序逻辑的混乱,使人看不懂你写的代码,或者编译器不能正确识别你的转换的意图,所以做出错误的转换方式。其次,C类型的转换很难查错。特别是在大型的工程中,你想找出一个因为 (uint)转换成 int而产生益出的问题,可能需要查看上千行包含"(int)"的代码。为了避免诸如此类情况的发生 C++引入了4种类型转换的方式。请记住,C的类型转换只是为C语言设计的,并不适合C++。C++支持C的类型转换只不过是为了向下兼容的考虑。

让我们来看看C++的4种类型转换(关于这4种类型转换的详细说明,请参见<C++ Programming Language> 3rd Edition):

static_cast<>()
dynamic_cast<>()
const_cast<>()
reinterpret_cast<>()

我们一个一个来说
================== static_cast ==================
static_cast<>() 
static_cast可以用来进行相关类型之见的转换,比如double 转成 float, float转成 int 以及 有关联的pointer之间,有关联的 class pointer 之间的转换。

========比如========

float FloatNum = 1.234;
int IntNum = static_cast<int>(FloatNum);    // IntNum = 1;

========或者========

class BaseClass{
public:
    BaseClass();
    virtual ~BaseClass();
};

class DerivedClass : public BaseClass{
public:
    DerivedClass();
    ~DerivedClass();
    void DoSomething(void);
};

BaseClass * pBaseClass = new BaseClass();
// 没问题,不过call pDerviedCalss->DoSomething()很有可能会crash
DerivedClass * pDerivedClass = static_cast<DerivedClass *>pBaseClass;

DerivedClass * pDerivedClass = new DerivedClass();
// 没问题,很安全
BaseClass * pBaseClass = static_cast<BaseClass *>(pDerivedClass);

值得注意的是 static_cast是在程序编译的时候检查类型转换是否符合要求,并不在程序运行期间进行检查,因为没有 runtime overhead, 对速度的影响比较小。所以在你对类型转换很有把握的时候,可以尽量的使用static_cast。另外  static_cast在转换指针的时候并不能保证转换前的指针地址和转换后的指针地址相同,特别是在多重继承的类结构中,指针地址经常会变化。

下面是一些通常比较危险的类型转换,

========包括========
unsigned 转 sign 比如 uint 转成 int
double 转 float
long 转 int (64位操作系统有危险,32位无)

这些转换都是值域大的转成值域小的数,或者无符号转成有符号。比如:

unsigned int k = 4294967290;
int m = static_cast<int>(k);

这里k已经超出了int的值域,所以 m的最后结果是 -6。所以在做以上的类型转换的时候,要特别的小心。


================== dynamic_cast ==================
dynamic_cast 是用来对相关的class 指针之间进行的类型转换。由于dynamic_cast在运行过程中对转换进行安全性检查,所以在很大程度上影响程序的运行速度,并且在便宜的时候需要打开runtime type info 的开关 /GR,所以并不推荐使用。

如果要使用dynamic_cast那么要求转换的类至少需要含一个虚函数,并且只能对类的指针进行转换操作,指针不包括 void *。 例如:

class BaseClass{
public:
    BaseClass();
    virtual ~BaseClass();
    virtual void DoSomething(void);
};

class DerivedClass : public BaseClass{
public:
    DerivedClass();
    ~DerivedClass();
    void DoSomething(void);
};

DerivedClass * pDerivedClass = new DerivedClass();
// 没问题
BaseClass * pBaseClass = dynamic_cast<DerivedClass *>(pDerivedClass);

BaseClass * pBaseClass = new BaseCalss();
// 有问题,基类转成派生类,dynamic_cast会返回null 所以 pDerivedClass == NULL
DerivedClass * pDerivedCalss = dynamic_cast<DerivedClass *>(pBaseClass);

================== const_cast ==================
顾名思义,就是把const变量转换成 non-const变量,或者把volatile转成non-volatile。这是最不推荐使用的一种转换,只有在特殊的情况下才会使用。如果你需要大量的使用const_cast,那么只能说明程序中存在着设计缺陷。

const_cast的使用如下:
float FloatNum = 12;
const float * pConstFloatPointer = &FloatNum;
// ok 这么用没问题
float * pFloatPointer = const_cast<float *>(pConstFloatPointer);
// 编译错误,const_cast只能进行const和non-const之间的转换
int * pFloatPointer = const_cast<int *>(pConstFloatPointer);

================== reinterpret_cast ==================
reinterpret_cast是最危险的一种转换类型,它并不对数据进行任何实际的转换操作,而是直接把数据当作另一种类型来使用(跟内存拷贝的功能差不多)。比如:

class ClassX{...};
class ClassY{...};

ClassX * pClassX = new ClassX();
// 没问题,不过除非classX和classY都是结构相同的interface,否则并不安全,程序很容易crash
ClassY * pClassY = reinterpret_cast<ClassY *>(pClassX);

reinterpet_cast比较有用的地方就是函数指针的转换,比如把一个指针存到一个函数指针数组中:

      typedef void (*FuncPtr)();
      FuncPtr FuncPtrArray[10];
      int DoSomething() {...};
      // 这里使用reinterpret_cast
      FuncPtrArray[0] = reinterpret_cast<FuncPtr>(&DoSomething);

总的来说,尽可能的使用这4种转换来清晰的表达你转换的目的,尽量不要使用C风格的转换。

================== Design Pattern ==================
今天的Design Pattern讲讲另外两个概念: Interface Inheritance 和 Implementation Inheritance。

上次Aear已经介绍了Inheritance 和 Delegation,并且说如果能用Delegation的地方,就最好不要使用 Inheritance。但是如果必须使用Inheritance怎么办?因此就出现了不同使用Inheritance(继承)的方式。第一种就是  Interface Inheritance。

简单的说,Interface Inheritance就定义一个 abstract class (抽象类),把所有提供的类方法都在这个抽象类中定义成纯虚函数,然后在派生类中实现这些虚函数。对于这个 abstract class,我们可以称它为: Interface。 (是不是有点象 COM?)。 比如在游戏中,所有的敌人都可以移动和攻击,但是不同的敌人类型,攻击和移动的具体方式都不一样。我们就可以用一个抽象类在表示所有的敌人,在派生类中具体实现不同移动和攻击方式。
下面让我们来看看代码:

class Enemy{
public:
    virtual void Move(void) = 0;
    virtual void Attack(void) = 0;
};

// 人类敌人
class HumanEnemy : public Enemy{
public:
    void Move(void) {...}; // 用2条腿走路
    void Attack(void) {...}; // 用拳头或武器攻击
};

// 怪物敌人
class MonsterEnemy : public Enemy{
public:
    void Move(void) {...}; // 用4跳腿走路
    void Attack(void) {...}; // 用牙齿和爪子攻击
};

在运行AI的时候我们不需要具体判断对方是人类还是敌人,直接调用 move和attack就行了,代码如下:

void CalculateAction( Enemy * pEnemy)
{
    pEnemy->Move();
    pEnemy->Attack();
}

main()
{
   ....
   HumanEnemy * pHumanEnemy = new HumanEnemy();
   MonsterEnemy * pMonsterEnemy = new MonsterEnemy();
   CalculateAction(static_cast<Enemy *>pHumanEnemy);
   CalculateAction(static_cast<Enemy *>pMonsterEnemy);
   ....
}

=========== 小分割线 ===========

关于implementation inheritance,就是Aear在上一章里举的关于CBitmap和CTexture的例子。其中CBitmap 只基类,提供了 GetBitmapHeight()方法。 CTexture是CBitmap的派生类,提供了GetTextureHeight()的方法。这种结构很容易使人产生程序逻辑结构的混乱,并不推荐使用。Aear的个人观点是:
    能使用 Delegation就用
    不能用Delegation就用 Interface Inheritance
    用不了Interface Inheritance就重新设计你的类结构,使之能使用前两种方式
    如果重新设计系统或者使用Interface Inheritance开销太大,再用Implementation Inheritance。

其实所有的Implementation Inheritance都可以通过Interface Inheritance来实现,具体来说,就是定义一个 abstract class基类,在此基础上,定义派生类的abstract class (派生类也是interface),如此定义下去,直到所有需要实现的类都拥有自己的interface class为止。

 
C++ Design Pattern(设计模式) 非四人帮的,类似网友的学习笔记本,不过写的还不错。 立即下载

相关推荐

java三角套利_三角对冲套利-EA原理全解析

它是两个直盘货币和一个交叉盘货币之间的相互对冲,交易员往往受到外界因素的影响无法严格执行造成亏损。该系统经过大量数据统计分析和严格的科学论证计算,并通过多年实盘交易验证可以达到稳定盈利。希望交易员严格按照交易规则执行。此策略利用交叉外汇对的市场价格与其合成价格的价差来实现套利,还以EUR/USD和GBP为例:1,我们关注三个外汇对:EUR/USD,GBP/USD,以及GBP/EUR2,计算GBP/...

weixin_29531897的博客 2418

继承(Inheritance)和实现(Implementation)的区别、抽象类

继承强调类之间的“是一个”关系,通过继承父类的属性和方法实现代码复用,而实现则强调类的行为,通过实现接口定义的抽象方法来实现多种行为。

m0_62257437的博客 994

CDO批量处理nc文件:5分钟搞定CMIP6数据双线性插值(附完整代码)

本文详细介绍了如何使用CDO工具链中的`remapbil`命令,快速实现CMIP6数据的批量双线性插值处理。通过环境配置、核心操作步骤、高级优化技巧及典型报错解决方案,帮助科研人员高效处理大规模nc文件,显著提升气象数据处理效率。

weixin_29267307的博客 292

设计模式:Interface Inheritance (接口继承)和 Implementation Inheritance(实现继承)

设计模式:Interface Inheritance (接口继承)和 Implementation Inheritance(实现继承) 先阅读《具体类、抽象类、接口》:http://blog.youkuaiyun.com/iw1210/article/details/33727491 纯虚函数(pure virtual):派生类继承这个函数,并实现该函数。 虚函数(impure virtual):派生类

iw1210的专栏 2541

在Ansys Simplorer中设计三相逆变器,并与Maxwell FEA耦合,实现160kW PMSM

在这篇博文中,我们将探讨如何使用设计三相逆变器,并将其与Ansys Maxwell中的电磁有限元分析模型耦合,以获得准确的系统级结果。Ansys Electronics为多域仿真提供了强大的生态系统,可实现跨各种物理领域的无缝集成。Maxwell用于电磁有限元分析 (FEA),Simplorer(Twin Builder) 用于系统级逆变器和控制器设计,Icepak用于电子热仿真。例如,我们将使用 Simplorer 介绍160 kW、8 极永磁同步电机 (PMSM)的逆变器设计过程。让我们开始吧!

jkh920184196的博客 1426

Docker版OnlyOffice中文字体配置全攻略:从字号调整到字体添加

本文详细介绍了在Docker版OnlyOffice中配置中文字体和调整字号的完整方案。通过容器内操作和配置文件修改,实现中文标准字号映射及思源、阿里巴巴等优质字体的集成,提升文档排版的规范性和专业性。特别针对企业级部署提供了性能优化建议和常见问题解决方案。

weixin_28309571的博客 137

C++-----reinterpret_cast

首先从英文字面的意思理解,interpret是“解释,诠释”的意思,加上前缀“re”,就是“重新诠释”的意思;cast在这里可以翻译成“转型”(在侯捷大大翻译的《深度探索C++对象模型》、《Effective C++(第三版)》中,cast都被翻译成了转型),这样整个词顺下来就是“重新诠释的转型”。我们知道变量在内存中是以“…0101…”二进制格式存储的,一个int型变量一般占用32个位(bit),参考下面的代码

weixin_45459266的博客 3975

国产机载操作系统天脉ACoreOS实战:从零搭建开发环境到应用移植

本文详细介绍了国产机载操作系统天脉ACoreOS的实战开发流程,从核心特性解析到开发环境搭建,再到VxWorks应用移植策略。重点阐述了其符合ARINC 653标准的时空分区架构如何保障高可靠性,并提供了从零创建分区工程、重构通信与任务代码的具体步骤,为开发者向这一国产化平台迁移提供了实用指南。

flower的专栏 634

《Effective Java》笔记系列 复合优于继承(实现继承:implementation inheritance)

什么情况下继承是安全的: 1、子类和超类在同一个包中 2、对于专门为了继承而蛇姐,并且具有很好的文档说明的类 继承也是非常安全的。 对于普通的具体类跨包继承是非常危险的。 继承打破了封装性,子类依赖于超类的实现细节,当超累发生变化,子类可能会遭到破坏 使用复合:在新的类中添加一个私有域,引用现有类的一个实例,用转发的方式复用现有类中对应的方法。 只有当确定A和B之前是is-a时才应该使用继承 如果...

mysql数据库 innodb存储引擎怎么创建好索引 286

YOLOv11改进策略【模型轻量化】| 使用 MoblieOne 模块,引入结构重参数化,提高模型检测效率

本文记录的是基于MobileOne的YOLOv11骨干网络改进方法研究。MobileOne的基础模块通过重参数化,。在将其替换YOLOv11的骨干网络后,实现模型轻量化。

Limiiiing的博客 1425

【参数配置】OpenClaw 的破解之道(Doom Loop)

本文深入解析了OpenClaw中的Doom Loop(死循环)问题及其应对策略。主要内容包括: Agent Loop的核心概念:基于ReAct范式,OpenClaw通过"思考-行动-观察"循环执行任务,但可能陷入无进展的死循环。 Doom Loop现象:Agent持续执行但任务进度为零,常见于四种工具调用场景:相同调用重复执行、调用不存在工具、轮询工具卡死、操作交替振荡。 OpenClaw的防御机制: 第一道防线:重试端断路器,通过上下文压缩熔断(最多3次)和总重试次数熔断(32-160次)防止无限重试。

海兰 4042

C++基本功和 Design Pattern系列(2) Type Cast, Interface Inheritance VS Implementation Inheritance

====================================================== 原创就是麻烦呀,最怕误人子弟....大家请把我的文章当参考,详细内容   还请参照 权威书籍 如果文中有错误和遗 漏,请指出,Aear会尽力更正, 谢谢!====================================================== 又到周末了,Aea

蚊子的Home-游戏开发 469

Plecs电力电子仿真专业教程-第一季 补充课程 Plecs的安装教程与软件下载

PLECS4.1.64免安装版本–点我下载 Plecs.Standalone-3.7.2版本--关注加私信给我可以提供下载链接 补充课程 Plecs的安装教程与软件下载 详细介绍Plecs软件的安装过程

1万+

【转】C 基本功和 Design Pattern系列 Type Cast, Interface Inheritance VS Implementation Inherita...

许多学过C的朋友一定还记得C语言中的类型转换,例如:float FloatNum = 1.234;int IntNum = (int)FloatNum;// IntNum = 1这是比较正常的类型转换,稍微危险一点的转换如下:float FloatNum = 1.234;float * pFloatPointer = &FloatNum;int *...

weixin_30810583的博客 93

深度学习工具包 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'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('DeepLearnToolbox'));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('state',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'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',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 = 'sigm';%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, 'Too big error');```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('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';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)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';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, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% 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'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 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, 'Too big error');```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('state',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, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',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, 'Too big error');%% ex3 neural net with dropoutrand('state',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, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % 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, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % 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, 'Too big error');%% 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('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % 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, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Effective_C++:36、区分接口继承(interface inheritance)和实现继承(implementation inheritance)

36、区分接口继承和实现继承 成员函数的接口一定会被继承,因为公有继承是“isa”的关系,只要可以用于基类对象上,就可以用于派生类对象上。 1、纯虚拟函数 声明一个纯虚拟函数的目的是让派生类只继承其接口。 纯虚拟函数必须被派生类重新声明,且在基类中通常没有定义。 但是,纯虚拟函数在基类中也是可以定义的,此时通常用于实现为其他非纯虚拟函数提供缺省行为。 2、非纯虚拟函数 声明一般(非纯...

l1dian11的博客 366

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

5.11.3. Implementation Using Inheritance

5.11.3. Implementation Using Inheritance 5.11.3.使用继承实现 While the built-in declarative partitioning is suitable for most common use cases, there are somecircumstances where a more flexible approach may be useful. Partitioning can be implemented usingtab..

在路上 477

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

class之間有三種關係,inheritance,implementation和association

 class之間有三種關係,inheritance,implementation和association。inheritance和implementation在C++、C#、Java都有直接支援,所以不難懂,但association,aggregation和composition在語言並沒有知接支援,到底三者有什麼差別呢?首先看association,下圖是個典型的assoication clas

freegodlee的专栏 3438

CS61B - Lec 9 - Implementation Inheritance(Extends)

CS61B - lec 9Implementation Inheritance: ExtendsEncapsulationCastingHigher Order Functions in Java Implementation Inheritance: Extends 上个lecture中介绍了interface - implements继承方法。interface中只是定义了类可以实现的方法,不...

fourier_transformer的博客 628

interface_cast做什么的?

1. 前面对interface_cast已经进行了详解,为加深理解,现单独把结果抛出来。 它本身是一个模板,如:interface_cast(reply.readStrongBinder()); 2. reply.readStrongBinder());返回的结果是一个新创建的BpBinder对象。 3. interface_cast(BpBinder);新创建一个BpMediaPlayer

MyArrow的专栏 1万+

C++接口实现总结

网上的例子,稍微有点错误。我给更改一下,附件上有源码!如有错误,请指正。 总结一下C++实现接口的技巧。       面向对象的语言诸如JAVA提供了Interface来实现接口,但C++却没有这样一个东西,尽管C++ 通过纯虚基类实现接口,譬如COM的C++实现就是通过纯虚基类实现的(当然MFC的COM实现用了嵌套类),但我们更愿意看到一个诸如 Interface的东西。下面就介绍一种解决办...

qimo601的专栏 1311

Effective C++之 Item 34 区分 inheritance of interface(接口继承)和 inheritance of implementation(实现继承)

(public) inheritance 这个表面上简单易懂的观念,一旦被近距离审视,就会被证明是由两个相互独立的部分组成的:inheritance of function interfaces(函数接口的继承)和 inheritance of function implementations(函数实现的继承)。这两种 inheritance 之间的差异正好符合本书 Introduction 中...

janeqi1987的专栏 362

C++中的static_cast,dynamic_cast,const_cast,reinterpret_cast

1 static_cast ( expression )  该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。它主要有如下几种用法:  ①用于类层次结构中基类和子类之间指针或引用的转换。    进行上行转换(把子类的指针或引用或对象转换成基类表示)是安全的;    进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是

gaokewoo的专栏 355

interface cast做什么的

interface cast做什么的

qq_44884706的博客 348

深挖C++:类和对象(中)

(先进后出)

xys_678的博客 246
上一篇: Struts配置
下一篇: ubuntu软件安装命令
zhy05
博客等级 码龄21年 21粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值