Effective C++ 2e Item11

128x64 OLED屏的救星:手把手教你用纯C实现轻量级多级菜单 本文针对资源受限的单片机开发场景,提供了一套用纯C语言实现128x64 OLED屏轻量级多级菜单的完整方案。该方案摒弃了传统的树形指针结构,创新性地采用哈希表进行菜单项管理,核心代码不足200行,内存占用极低,逻辑清晰且易于维护。文章详细阐述了架构设计、实战演练及性能优化技巧,是STM32、ESP8266等小内存MCU项目的理想选择。 阅读详情

构造函数,析构函数和赋值操作符

几乎所有的类都有一个或多个构造函数,一个析构函数和一个赋值操作符。这没什么奇怪的,因为它们提供的都是一些最基本的功能。构造函数控制对象生成时的基本操作,并保证对象被初始化;析构函数摧毁一个对象并保证它被彻底清除;赋值操作符则给对象一个新的值。在这些函数上出错就会给整个类带来无尽的负面影响,所以一定要保证其正确性。本章我将指导如何用这些函数来搭建一个结构良好的类的主干。


条款11: 为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

看下面一个表示String对象的类:

// 一个很简单的String类
class String {
public:
  String(const char *value);
  ~String();

  ...                           // 没有拷贝构造函数和operator=

private:
  char *data;
};

String::String(const char *value)
{
  if (value) {
    data = new char[strlen(value) + 1];
    strcpy(data, value);
  }
  else {
    data = new char[1];
    *data = '/0';
  }
}

inline String::~String() { delete [] data; }

请注意这个类里没有声明赋值操作符和拷贝构造函数。这会带来一些不良后果。

如果这样定义两个对象:

String a("Hello");
String b("World");

其结果就会如下所示:

a:  data——> "Hello/0"
b:  data——> "World/0"

对象a的内部是一个指向包含字符串"Hello"的内存的指针,对象b的内部是一个指向包含字符串"World"的内存的指针。如果进行下面的赋值:

b = a;

因为没有自定义的operator=可以调用,C++会生成并调用一个缺省的operator=操作符(见条款45)。这个缺省的赋值操作符会执行从a的成员到b的成员的逐个成员的赋值操作,对指针(a.data和b.data) 来说就是逐位拷贝。赋值的结果如下所示:

a:  data --------> "Hello/0"
            /
b:  data --/       "World/0"

这种情况下至少有两个问题。第一,b曾指向的内存永远不会被删除,因而会永远丢失。这是产生内存泄漏的典型例子。第二,现在a和b包含的指针指向同一个字符串,那么只要其中一个离开了它的生存空间,其析构函数就会删除掉另一个指针还指向的那块内存。

String a("Hello");                 // 定义并构造 a

{                                  // 开一个新的生存空间
  String b("World");               // 定义并构造 b

  ...

  b = a;                           // 执行 operator=,
                                   // 丢失b的内存

}                                  // 离开生存空间, 调用
                                   // b的析构函数

String c = a;                      // c.data 的值不能确定!
                                   // a.data 已被删除

例子中最后一个语句调用了拷贝构造函数,因为它也没有在类中定义,C++以与处理赋值操作符一样的方式生成一个拷贝构造函数并执行相同的动作:对对象里的指针进行逐位拷贝。这会导致同样的问题,但不用担心内存泄漏,因为被初始化的对象还不能指向任何的内存。比如上面代码中的情形,当c.data用a.data的值来初始化时没有内存泄漏,因为c.data没指向任何地方。不过,假如c被a初始化后,c.data和a.data指向同一个地方,那这个地方会被删除两次:一次在c被摧毁时,另一次在a被摧毁时。

拷贝构造函数的情况和赋值操作符还有点不同。在传值调用的时候,它会产生问题。当然正如条款22所说明的,一般很少对对象进行传值调用,但还是看看下面的例子:

void doNothing(String localString) {}

String s = "The Truth Is Out There";

doNothing(s);

一切好象都很正常。但因为被传递的localString是一个值,它必须从s通过(缺省)拷贝构造函数进行初始化。于是localString拥有了一个s内的指针的拷贝。当doNothing结束运行时,localString离开了其生存空间,调用析构函数。其结果也将是:s包含一个指向localString早已删除的内存的指针。

顺便指出,用delete去删除一个已经被删除的指针,其结果是不可预测的。所以即使s永远也没被使用,当它离开其生存空间时也会带来问题。

解决这类指针混乱问题的方案在于,只要类里有指针时,就要写自己版本的拷贝构造函数和赋值操作符函数。在这些函数里,你可以拷贝那些被指向的数据结构,从而使每个对象都有自己的拷贝;或者你可以采用某种引用计数机制(见条款 M29)去跟踪当前有多少个对象指向某个数据结构。引用计数的方法更复杂,而且它要求构造函数和析构函数内部做更多的工作,但在某些(虽然不是所有)程序里,它会大量节省内存并切实提高速度。

对于有些类,当实现拷贝构造函数和赋值操作符非常麻烦的时候,特别是可以确信程序中不会做拷贝和赋值操作的时候,去实现它们就会相对来说有点得不偿失。前面提到的那个遗漏了拷贝构造函数和赋值操作符的例子固然是一个糟糕的设计,那当现实中去实现它们又不切实际的情况下,该怎么办呢?很简单,照本条款的建议去做:可以只声明这些函数(声明为private成员)而不去定义(实现)它们。这就防止了会有人去调用它们,也防止了编译器去生成它们。关于这个俏皮的小技巧的细节,参见条款27。

关于本条款中所用到的那个String类,还要注意一件事。构造函数体内,在两个调用new的地方都小心地用了[],尽管有一个地方实际只需要单个对象。正如条款5所说,在配套使用new和delete时一定要采用相同的形式,所以这里也这么做了。一定要经常注意,当且仅当相应的new用了[]的时候,delete才要用[]。

 

通过两个mark点确定某一个点的位置 read_image (Image0, '0.bmp') binary_threshold (Image0, Region, 'max_separability', 'dark', UsedThreshold) connection (Region, ConnectedRegions) fill_up (ConnectedRegions, RegionFillUp) select_shape_std (RegionFillUp, SelectedRegions, 'max_area', 70) red... 阅读详情

相关推荐

缠论 公式 自动画线 画笔 中枢 买卖点 源代码

【代码】缠论 公式 自动画线 画笔 中枢 买卖点 源代码。

weixin_40835859的博客 2万+

如果动态的为本地C++类的成员分配空间,则必须实现复制构造函数--的说明

问题引出? 1、定义如下的类: class CMessage { public: CMessage(const char *text = "Default Message.") { m_pMessage = new char[strlen(text)+1]; strcpy_s(m_pMessage, strlen(text)+1, text); } ~CMessage() {

872

【模拟电子设计实战】开源!基于Multisim与AD620的心电采集电路仿真与优化

本文详细介绍了基于Multisim与AD620的心电采集电路仿真与优化实战。通过分析心电信号采集的挑战,重点讲解了AD620仪表放大器和OP07运算放大器的选型优势及电路设计技巧,包括对抗50Hz工频干扰和基线漂移的优化方法。文章还分享了Multisim仿真参数设置与实测对比经验,最终实现性能达标的心电采集电路设计。

weixin_30555125的博客 96

动态分配内存的类定义拷贝构造函数和赋值运算符、C++幕后所做的事情以及禁止这些

1、C++编译可能默认生成一些函数 通过它的时候。如果自定义类没有声明下列函数,C++编译器会声明自己的版本。这些函数是:一个拷贝构造函数,一个赋值运算符,一个析构函数,一对取址运算符。另外,如果你没有声明任何构造函数,它也将为你声明一个缺省构造函数。 class Empty{}; //等同于以下 class Empty { public: Empty();//缺省构造函数

一个菜鸟的博客 1293

数据分析实战:如何用皮尔逊相关系数避免伪相关陷阱(附Python代码)

本文通过实战案例与Python代码,深入解析了皮尔逊相关系数在数据分析中的应用与常见陷阱。文章重点揭示了如何识别与避免由混杂变量导致的伪相关,并介绍了通过可视化、敏感性分析、分层分析与偏相关分析等方法来检验相关性的可靠性,帮助分析师建立严谨的相关性思维。

weixin_29051245的博客 413

HC32 CAN通信

qqa

zhaopenglihui的博客 5436

关于拷贝构造函数和赋值运算符

 作者:冯明德重点:包含动态分配成员的类 应提供拷贝构造函数,并重载"="赋值操作符。 以下讨论中将用到的例子: class CExample{public:CExample(){pBuffer=NULL; nSize=0;}~CExample(){delete pBuffer;}void Init(int n){ pBuffer=new char[n]; nSize=n;}private:cha

792

近五年体内微/纳米机器人赋能肿瘤精准治疗综述:以 GBM 为重点

摘要 微/纳米机器人在实体瘤治疗领域展现出突破性潜力,通过主动运动能力解决传统纳米药物递送效率低、渗透不足等核心问题。2021-2025年间形成三条技术路线:1) 磁驱、声驱等运动增强递送实现深层渗透;2) 与免疫治疗融合实现原位免疫唤醒;3) 针对胶质母细胞瘤开发跨屏障递送系统。研究重点从单一运动性能转向"运动-分布-疗效"的系统评价,需建立标准化指标评估运动学参数、肿瘤分布均匀性和安全性。未来挑战在于临床转化的可制造性、闭环操控及生物相容性优化,特别是对血脑屏障穿透等复杂场景的系统集

AllenLV的博客 5175

关于为什么要为需要动态分配内存的类声明一个拷贝构造函数和一个赋值操作符

之前一直不是很明白为什么当一个类中还有一个要动态分配内存的指针之类的数据成员时一定要声明一个拷贝构造函数和一个赋值操作符。(尽管你在构造函数和析构函数中分别进行了new和delete操作)今天看了effective C++的11章才有所明白。原因是看下面介绍:当你没定义这2个函数时,那么当你声明2个对象时,比如tmpclass a("hello");tmpclass b("

dick_china的专栏 1684

【2025国赛C题】高教社杯全国大学生数学建模竞赛C题思路+代码+论文

【2025国赛C题】高教社杯全国大学生数学建模竞赛C题思路+代码+论文

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 2905

simulink建模仿真实例1000例--第375例:基于Simulink进行复杂交通流的仿真建模

特点多车互动:模拟多个车辆之间的相互作用。动态变化:交通流量随时间和事件(如事故、天气变化)而变化。多样化驾驶行为:考虑不同的驾驶员行为模式(激进型、保守型等)。挑战准确性:准确地模拟各种因素对交通流的影响。实时性:处理大量车辆数据,并迅速做出反应。可扩展性:支持从简单场景到复杂城市交通网络的扩展。首先明确要模拟的任务内容。模拟不同类型的车辆(轿车、卡车、公交车等)。考虑不同驾驶员的行为模式。分析交通拥堵、事故对交通流的影响。

xiaoheshang_123的博客 203

关于拷贝构造函数

用到拷贝构造函数的地方有3种情况: 1)一个对象用于给另外一个对象进行初始化(赋值初始化) 2)一个对象作为函数参数,以值传递的方式传入函数体 3)一个对象作为函数返回值,以值传递的方式从函数返回 为什么要用到拷贝构造函数 原则:对于凡是包含动态分配成员或包含指针成员的类都应该提供拷贝构造函数 对于第一种情况,先用一个例子进行以下的说明: //这个类的主要特点是包含指向其他资源的指针

霾猿的博客 341

lammps 案例in文件汇总

进阶案例: 聚乙烯和石墨烯界面pull out模拟代码 反应力场reax/c设置方法及案例解析 石墨烯热导率模拟代码(NEMD方法) 圆锥形SiC纳米磨削单晶硅源代码 高熵合金FeNiCrCoCu纳米压痕模拟代码 fix indent命令实现纳米摩擦及摩擦力计算 Fe原子辐照轰击多层石墨烯模拟代码 铝基石墨烯复合物压缩变形in文件源代码 石墨烯自动卷曲到Fe纳米线模拟源代码 铝/石墨烯复合物结晶过程lammps模

lammps_jiayou的博客 9446

Effective C++ 2e Item5

内存管理C++中涉及到的内存的管理问题可以归结为两方面:正确地得到它和有效地使用它。好的程序员会理解这两个问题为什么要以这样的顺序列出。因为执行得再快、体积再小的程序如果它不按你所想象地那样去执行,那也一点用处都没有。“正确地得到”的意思是正确地调用内存分配和释放程序;而“有效地使用”是指写特定版本的内存分配和释放程序。这里,“正确地得到”显得更重要一些。然而说到正确性,C++其实从C继承

lostmouse的专栏 1199

jre9下载 jdk9

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

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

Effective C++ 2e Item50

条款50: 提高对C++的认识C++中有很多 "东西":C,重载,面向对象,模板,例外,名字空间。这么多东西,有时让人感到不知所措。怎么弄懂所有这些东西呢?C++之所以发展到现在这个样子,在于它有自己的设计目标。理解了这些设计目标,就不难弄懂所有这些东西了。C++最首要的目标在于:· 和C的兼容性。很多很多C还存在,很多很多C程序员还存在。C++利用了这一基础,并建立在 ---- 我是

lostmouse的专栏 1376

Devexpress16.2.6破解工具

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

Effective C++ 2e Item27

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

lostmouse的专栏 1301

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Effective C++ 2e Item29

类和函数: 实现C++是一种高度类型化的语言,所以,给出合适的类和模板的定义以及合适的函数声明是整个设计工作中最大的一部分。按理说,只要这部分做好了,类、模板以及函数的实现就不容易出问题。但是,往往人们还是会犯错。犯错的原因有的是不小心违反了抽象的原则:让实现细节可以提取类和函数内部的数据。有的错误在于不清楚对象生命周期的长短。还有的错误起源于不合理的前期优化工作,特别是滥用inline关

lostmouse的专栏 1157

Effective C++ 2e Item16

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

lostmouse的专栏 979

Effective C++ 2e Item17

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

lostmouse的专栏 966

Effective C++ 2e Item46

条款46: 宁可编译和链接时出错,也不要运行时出错除了极少数情况下会使C++抛出异常(例如,内存耗尽 ---- 见条款7)外,运行时错误的概念和C++没什么关系,就象在C中一样。没有下溢,上溢,除零检查;没有数组越界检查,等等。一旦程序通过了编译和链接,你就得靠自己了 ---- 一切后果自负。这很象跳伞运动,一些人从中找到了刺激,另一些人则吓得摔成了残废。这一思想背后的动机当然在于效率:没有运

lostmouse的专栏 1167

Effective C++ 2e Item12

条款12: 尽量使用初始化而不要在构造函数里赋值看这样一个模板,它生成的类使得一个名字和一个T类型的对象的指针关联起来。templateclass NamedPtr {public:  NamedPtr(const string& initName, T *initPtr);  ...private:  string name;  T *ptr;};(因为有指针成员的对象在进行拷贝

lostmouse的专栏 948

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

《Effective Modern C++》Item 1总结

<Effective Modern C++>理解模板类型推导总结

Ron的专栏 659

Effective Modern C++ Item 5

啊,写出下面的代码是简单愉快的,int x; 等一下,该死。我忘记初始化了,因此它的值是不确定的。

ねぇ。あなたは何色になりたい 523

Modern Effective C++ item 15:尽可能的使用constexpr

当constexpr应用于函数时,表示函数可以在编译期执行,因为参数也是编译期常量。常量表达式构造函数拥有和常量表达式函数相同的退化特性,当它的实参不是常量表达式的时候,构造函数可以退化为普通构造函数,当然,这么做的前提是类型的声明对象不能为常量表达式值。正常工作,因为 10 是一个常量表达式,size(10) 可以在编译时计算其结果,并用于初始化 constexpr 变量 s_constexpr。constexpr还能定义一个常量表达式函数,即constexpr函数,常量表达式函数的返回值可以在编译。

_ 1120

Effective Modern C++ - item 19 - shared_ptr

总结过的关于shared_ptr:https://blog.youkuaiyun.com/qq_35865125/article/details/88918909 , 有分析如何自己实现shared_ptr。 ----shared_ptr出现于c++ 11, 可以有很多很多个shared_ptr对象指向同一个资源(某个类的实例), ,这些shared_ptr 共同拥有这个资源。 优点: 就像是...

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

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值