Effective C++ 2e Item16

《Effective C#》Item 16:尽量减少垃圾产生的数量 对于.Net所写一般程序来说,都属于托管程序,内存的释放和回收是由Garbage Collector完成。但是相对于栈上内存操作而言,GC回收堆上的内存,会消耗更多的CPU时间,这方面的内容可以参看这篇文章。http://blog.youkuaiyun.com/knight94/archive/2006/08/05/1023352.aspx 因此如果让GC不停的释放和回收内存,会造成程序性能的下降 阅读详情

条款16: 在operator=中对所有数据成员赋值

条款45说明了如果没写赋值运算符的话,编译器就会为你生成一个,条款11则说明了为什么你会经常不喜欢编译器为你生成的这个赋值运算符,所以你会想能否有个两全其美的办法,让编译器生成一个缺省的赋值运算符,然后可以有选择地重写不喜欢的部分。这是不可能的!只要想对赋值过程的某一个部分进行控制,就必须负责做赋值过程中所有的事。

实际编程中,这意味着写赋值运算符时,必须对对象的每一个数据成员赋值:

template<class T>          // 名字和指针相关联的类的模板
class NamedPtr {           // (源自条款12)
public:
  NamedPtr(const string& initName, T *initPtr);
  NamedPtr& operator=(const NamedPtr& rhs);

private:
  string name;
  T *ptr;
};

template<class T>
NamedPtr<T>& NamedPtr<T>::operator=(const NamedPtr<T>& rhs)
{
  if (this == &rhs)
    return *this;              // 见条款17

  // assign to all data members
  name = rhs.name;             // 给name赋值

  *ptr = *rhs.ptr;             // 对于ptr,赋的值是指针所指的值,
                               // 不是指针本身

  return *this;                // 见条款15
}

初写这个类时当然很容易记住上面的原则,但同样重要的是,当类里增加新的数据成员时,也要记住更新赋值运算符函数。例如,打算升级NamedPtr模板使得名字改变时附带一个时间标记,那就要增加一个新的数据成员,同时需要更新构造函数和赋值运算符。但现实中,因为忙于升级类的具体功能和增加新的成员函数等,这一点往往很容易被忘记。

当涉及到继承时,情况就会更有趣,因为派生类的赋值运算符也必须处理它的基类成员的赋值!看看下面:

class Base {
public:
  Base(int initialValue = 0): x(initialValue) {}

private:
  int x;
};

class Derived: public Base {
public:
  Derived(int initialValue)
  : Base(initialValue), y(initialValue) {}

  Derived& operator=(const Derived& rhs);

private:
  int y;
};

逻辑上说,Derived的赋值运算符应该象这样:

// erroneous assignment operator
Derived& Derived::operator=(const Derived& rhs)
{
  if (this == &rhs) return *this;    // 见条款17

  y = rhs.y;                         // 给Derived仅有的
                                     // 数据成员赋值

  return *this;                      // 见条款15
}

不幸的是,它是错误的,因为Derived对象的Base部分的数据成员x在赋值运算符中未受影响。例如,考虑下面的代码段:

void assignmentTester()
{
  Derived d1(0);                      // d1.x = 0, d1.y = 0
  Derived d2(1);                      // d2.x = 1, d2.y = 1

  d1 = d2;         // d1.x = 0, d1.y = 1!
}

请注意d1的Base部分没有被赋值操作改变。

解决这个问题最显然的办法是在Derived::operator=中对x赋值。但这不合法,因为x是Base的私有成员。所以必须在Derived的赋值运算符里显式地对Derived的Base部分赋值。

也就是这么做:

// 正确的赋值运算符
Derived& Derived::operator=(const Derived& rhs)
{
  if (this == &rhs) return *this;

  Base::operator=(rhs);    // 调用this->Base::operator=
  y = rhs.y;

  return *this;
}

这里只是显式地调用了Base::operator=,这个调用和一般情况下的在成员函数中调用另外的成员函数一样,以*this作为它的隐式左值。Base::operator=将针对*this的Base部分执行它所有该做的工作——正如你所想得到的那种效果。

但如果基类赋值运算符是编译器生成的,有些编译器会拒绝这种对于基类赋值运算符的调用(见条款45)。为了适应这种编译器,必须这样实现Derived::operator=:

Derived& Derived::operator=(const Derived& rhs)
{
  if (this == &rhs) return *this;

  static_cast<Base&>(*this) = rhs;      // 对*this的Base部分
                                        // 调用operator=
  y = rhs.y;

  return *this;
}

这段怪异的代码将*this强制转换为Base的引用,然后对其转换结果赋值。这里只是对Derived对象的Base部分赋值。还要注意的重要一点是,转换的是Base对象的引用,而不是Base对象本身。如果将*this强制转换为Base对象,就要导致调用Base的拷贝构造函数,创建出来的新对象(见条款M19)就成为了赋值的目标,而*this保持不变。这不是所想要的结果。

不管采用哪一种方法,在给Derived对象的Base部分赋值后,紧接着是Derived本身的赋值,即对Derived的所有数据成员赋值。

另一个经常发生的和继承有关的类似问题是在实现派生类的拷贝构造函数时。看看下面这个构造函数,其代码和上面刚讨论的类似:

class Base {
public:
  Base(int initialValue = 0): x(initialValue) {}
  Base(const Base& rhs): x(rhs.x) {}

private:
  int x;
};

class Derived: public Base {
public:
  Derived(int initialValue)
  : Base(initialValue), y(initialValue) {}

  Derived(const Derived& rhs)      // 错误的拷贝
  : y(rhs.y) {}                    // 构造函数

private:
  int y;
};

类Derived展现了一个在所有C++环境下都会产生的bug:当Derived的拷贝创建时,没有拷贝其基类部分。当然,这个Derived对象的Base部分还是创建了,但它是用Base的缺省构造函数创建的,成员x被初始化为0(缺省构造函数的缺省参数值),而没有顾及被拷贝的对象的x值是多少!

为避免这个问题,Derived的拷贝构造函数必须保证调用的是Base的拷贝构造函数而不是Base的缺省构造函数。这很容易做,只要在Derived的拷贝构造函数的成员初始化列表里对Base指定一个初始化值:

class Derived: public Base {
public:
  Derived(const Derived& rhs): Base(rhs), y(rhs.y) {}

  ...

};

现在,当用一个已有的同类型的对象来拷贝创建一个Derived对象时,它的Base部分也将被拷贝了。

当KCF遇见卡尔曼滤波:视觉跟随算法的动态优化实战 本文探讨了KCF算法与卡尔曼滤波在视觉跟随算法中的动态优化实践,通过深度融合策略提升目标跟踪的鲁棒性和实时性。特别针对机器人应用场景,详细解析了在Jetson等嵌入式平台上的优化技巧,包括计算图优化、内存访问优化和多线程流水线设计,实现了30FPS@1080p的稳定跟踪性能。 阅读详情

相关推荐

SAP成本核算变式OKKN配置详解:从CK11N到CK24,手把手教你搞定标准成本发布

本文深入解析SAP成本核算变式OKKN的配置原理与实战应用,涵盖从CK11N到CK24的标准成本发布全流程。详细讲解数量结构控制、价值结构配置及间接费用计算规则,帮助成本会计精准掌握标准成本计算逻辑,解决BOM版本选择、工艺路线获取等常见问题,提升企业成本管理效率。

weixin_27219587的博客 292

重载操作符operator=()简单用法(类对象初始化方法之一:给对象赋值)

用C++重载操作符operator=()可以给一个该类的对象赋值,把这个对象当成整数一样来赋值。下面是具体的用法示例 #include <windows.h> #include <QDebug> class NC { public: BYTE b=5; NC() {} NC & operator =(const BYTE &va...

净无邪博客 1158

Arduino MLX90393磁力计驱动库:高精度三轴霍尔传感器开发指南

三轴霍尔效应磁力计是嵌入式系统中实现无接触角度检测、电子罗盘与电流传感的核心器件。其工作原理基于霍尔电压随外磁场矢量变化的物理特性,通过I²C接口输出高分辨率(16/20-bit)XYZ轴原始数据,并集成温度补偿与数字滤波功能。技术价值体现在确定性响应、低功耗(典型0.5 μA待机)及强抗干扰能力,适用于电池供电设备与实时操作系统环境。典型应用场景包括电机位置反馈、永磁体旋转角度解算、工业编码器和地磁导航。本库专为Arduino生态优化,深度封装MLX90393寄存器协议与自校准流程,同时兼容STM32、E

weixin_29363791的博客 642

C++编程语言中赋值运算符重载函数(operator=)介绍

首先介绍为什么要对赋值运算符“=”进行重载。某些情况下,当我们编写一个类的时候,并不需要为该类重载“=”运算符,因为编译系统为每个类提供了默认的赋值运算符“=”,使用这个默认的赋值运算符操作类对象时,该运算符会把这个类的所有数据成员都进行一次赋值操作。int b;int c;对这个类的对象进行赋值时,使用默认的赋值运算符是没有问题的。int b;int c;

liitdar的博客 11万+

高通ISP模块全解析:从Raw到JPEG的18个关键处理步骤(附避坑指南)

本文全面解析高通ISP模块从Raw到JPEG的18个关键处理步骤,涵盖原始数据预处理、色彩科学处理链、画质增强与降噪等核心环节。通过实战调优经验,揭示ISP架构中的技术原理与工程实践要点,帮助开发者避免常见问题,提升移动影像处理质量。

weixin_30399155的博客 360

Unity2018连接MySQL数据库

当前在做的一个Unity项目需要连接到MySQL数据库,弄了一整天,排了很多错,终于在Unity上成功连接到MySQL数据库了,所以分享一下,避免有这个需求的朋友不用花那么多时间。 我使用的软件是 Unity20184.0f1 + mysql-8.0.24 导入 MySql.Data.dll 首先需要把 MySql.Data.dll 导入到Assets/Plugins 这个dll需要安装Connector/NET,在安装目录\Assemblies\v4.0中拿到,最好不要下载版本太高的,版本太高导入的时候

ZLX的博客 9451

Effective C++ 条款16: 在operator=中对所有数据成员赋值

#include using namespace std; class BaseA { public: int _i; BaseA(int i): _i(i){}; BaseA(const BaseA& rhs); BaseA& operator=(const B

xrloyx的专栏 507

Trae CN 使用入门指南

【代码】Trae CN 使用入门指南。

weixin_42551921的博客 8771

条款 16: 在 operator=中对所有数据成员赋值

实际编程中,这意味着写赋值运算符时,必须对对象的每一数据成员赋值: template // 名字和指针相关联的类的模板 class NamedPtr { // (源自条款 12) public: NamedPtr(const string& initName, T *initPtr); NamedPtr& operator=(const NamedPtr& rhs); private: st

lujiandong1的专栏 627

飞牛fnNAS虚拟机开启OVS导致失联的解决

摘要:用户在使用飞牛NAS时发现开启OVS网络功能后导致NAS失联。通过多种尝试(包括开关OVS、更换系统版本、手工配置、更换网卡、处理器检查等)后发现,OVS启用状态下DHCP无法获取IP地址,手动设置IP可暂时恢复网络。但重启后问题依旧,初步判断为OVS功能存在bug。目前临时解决方案是在需要时手动开关OVS,或考虑其他虚拟化方案。用户计划后续探索替代方案,并等待官方修复该问题。

dgnankai的专栏 4339

Open-AutoGLM 实战:手把手教你用 AI 操作手机「喂饭教程」

Open-AutoGLM 是一个由智谱AI开源的手机操作智能体框架,由手机端智能助手框架Phone Agent和9B大小的模型AutoGLM-Phone-9B组成,借助ADB自动执行点击、滑动、输入等操作——用户只需用自然语言描述任务,系统便能自动规划并完成整个操作流程。

blues_C的博客 1267

Effective C++ 2e Item27

条款27: 如果不想使用隐式生成的函数就要显式地禁止它假设想写一个类模板Array,它所生成的类除了可以进行上下限检查外,其它行为和C++标准数组一样。设计中面临的一个问题是怎么禁止掉Array对象之间的赋值操作,因为对标准C++数组来说赋值是不合法的:double values1[10];double values2[10];values1 = values2;           

lostmouse的专栏 1301

C#上位机国产化适配全方案:兼容统信UOS+鲲鹏/昇腾+国产PLC,可直接交付国企项目

去年下半年,我帮天津滨海新区一家给一汽丰田做配套的汽车零部件国企,完成了3条产线、12套C#上位机的全栈国产化适配。这个项目的背景很典型,也很戳中国企客户的命门:一开始客户找了两家本地的集成商,都没搞定:第一家只会用.NET Framework,根本不知道怎么在统信UOS上跑C#;第二家勉强用.NET Core 3.1跑起来了,但和汇川国产PLC的通信丢包率高达1.2%,产线根本不敢用。我们接手后,用了2个月完成全栈适配:从Windows Server 2019迁移到统信UOS 1070d服务器版,从.NE

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 499

Effective C++ 2e Item17

 条款17: 在operator=中检查给自己赋值的情况做类似下面的事时,就会发生自己给自己赋值的情况:class X { ... };X a;a = a;                     // a赋值给自己这种事做起来好象很无聊,但它完全是合法的,所以看到程序员这样做不要感到丝毫的怀疑。更重要的是,给自己赋值的情况还可以以下面这种看起来更隐蔽的形式出现:

lostmouse的专栏 966

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

android 蓝牙通讯demo

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

Effective C++ item 01-04 随笔

学习是分享和合作式的! 转载请注明出处:http://blog.youkuaiyun.com/wdzxl198/article/details/9219115;         最近看《Effective C++》这本书,就做个简单的图片式的小随笔吧。推荐在线看此书的网址:http://www.kuqin.com/effectivec2e/index.html,还是不错的; 那就开始:

Atlas2013的专栏 1454

深度学习工具包 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")

c++ item

C++书单: 1:第一本   基础好一些的,可以看Stanley B. Lippman的C++ Primer,基础不太好的话,可以看Stanley B. Lippman的  Essential C++ 2:第二本   Pike和Kernighan的The Practice of Programming 3:第三本   Bruce Eckel写的、台湾候捷译的Thinking in C+

u012526180的专栏 3020

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Effective C++ 2e Item2

 条款2:尽量用而不用是的,scanf和printf很轻巧,很高效,你也早就知道怎么用它们,这我承认。但尽管他们很有用,事实上scanf和printf及其系列还可以做些改进。尤其是,他们不是类型安全的,而且没有扩展性。因为类型安全和扩展性是C++的基石,所以你也要服从这一点。另外,scanf/printf系列函数把要读写的变量和控制读写格式的信息分开来,就象古老的FORTRAN那样。是该向

lostmouse的专栏 1069

[翻译] Effective C++, 3rd Edition, 附录 B. 第二和第三版之间的 Item 映射

附录 B. 第二和第三版之间的 Item 映射作者:Scott Meyers译者:fatalerror99 (iTePubs Nirvana)发布:http://blog.youkuaiyun.com/fatalerror99/Effective C++ 的第三版在很多方面与第二版不同,其中最引人注目的是它包含很多新的信息。然而,第二版的大部分内容依然保留在第三版中,虽然经常会改变形式和位置

艺术编程 5819

effective c++ item 25-29

effective c++

weixin_44609676的博客 449

Effective C++ Item 16 成对使用new和delete时要采取相同形式

经验:如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。如果你在new表达式中不使用[],一定不要在相应的delete表达式中使用[]。          单一对象和对象数组的内存示意图: Object          单一对象            对象数组 n Object Object

720

More Effective C++ Item M32:在未来时态下开发程序

2. 杂项我们现在到了接近结束的部分了,这章讲述的是一些不属于前面任一章节的指导原则。开始两个是关于C++软件开发的,描述的是设计适应变化的系统。面向对象的一个强大之处是支持变化,这两个条款描述具体的步骤来增强你的软件对变化的抵抗能力。然后,我们分析怎么在同一程序中进行C和C++混合编程。这必然导致考虑语言学之外的问题,但C++存在于真实世界中,所以有时我们必须面对这种事情。最后,我将概述C++语

taodm的专栏 1064

读书笔记 effective c++ Item 48 了解模板元编程

1. TMP是什么? 模板元编程(template metaprogramming TMP)是实现基于模板的C++程序的过程,它能够在编译期执行。你可以想一想:一个模板元程序是用C++实现的并且可以在C++编译器内部运行的一个程序,它的输出——从模板中实例化出来的C++源码片段——会像往常一样被编译。 2. 使用TMP的优势 如果这没有冲击到你,是因为你没有足够尽力去想。   C++不是...

HarlanC的专栏 200

读书笔记 effective c++ Item 52 如果你实现了placement new,你也要实现placement delete

1. 调用普通版本的operator new抛出异常会发生什么? Placement new和placement delete不是C++动物园中最常遇到的猛兽,所以你不用担心你对它们不熟悉。当你像下面这样实现一个new表达式的时候,回忆一下Item 16和Item 17: 1 Widget *pw = new Widget;   两个函数会被调用:一个是调用operator new来分配...

HarlanC的专栏 207

读书笔记 effective c++ Item 5 了解c++默认生成并调用的函数

1 编译器会默认生成哪些函数  什么时候空类不再是一个空类?答案是用c++处理的空类。如果你自己不声明,编译器会为你声明它们自己版本的拷贝构造函数,拷贝赋值运算符和析构函数,如果你一个构造函数都没有声明,编译器同样会为你声明一个默认拷贝构造函数。这些所有的函数会是public和inline的(Item30)。因此,如果你写了下面的类: 1 class Empty{}; 本质上来说和下面的类...

HarlanC的专栏 179

伺服压机软件架构拆解:上位机与下位机的职责划分与工程实践

在工业自动化控制系统中,软件架构的分层设计直接决定设备的稳定性与开发效率。特别是对于伺服压机这类对实时性要求严苛的设备,通常将系统划分为上位机与下位机两部分,本质是按控制周期和功能边界进行职责切分。下位机承担毫秒级的位置、速度与压力闭环控制及安全保护,保证实时性不受操作系统干扰;上位机则专注于配方管理、数据追溯与人机交互等非实时业务,两者通过Modbus TCP或自定义TCP协议实现松耦合通信。合理区分上位机管控层与下位机实时层的架构边界,是设备稳定运行的关键前提。这种分层思想不仅适用于伺服压机,也广泛适用

weixin_34389926的博客 201

读书笔记 effective c++ Item 13 用对象来管理资源

正文回到顶部1.不要手动释放从函数返回的堆资源假设你正在处理一个模拟Investment的程序库,不同的Investmetn类型从Investment基类继承而来,1classInvestment{...};//rootclassofhierarchyof23//investmenttypes进一步假设这个程序库通过一个工厂函数(Item 7)来...

weixin_34007886的博客 64
上一篇: Effective C++ 2e Item15
下一篇: Effective C++ 2e Item17
lostmouse
博客等级 码龄26年 22粉丝 63原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值