[翻译] Effective C++, 3rd Edition, Item 4: 确保 objects(对象)在使用前被初始化

别再被网站识别成机器人了!用Python的undetected_chromedriver+Selenium实现无痕自动化 本文详细介绍了如何利用Python的undetected_chromedriver和Selenium实现无痕自动化,突破现代网站的反爬系统。通过修正浏览器指纹、模拟人类操作行为,并结合实战案例,帮助开发者构建难以被识别的自动化脚本,适用于电商监控等场景。 阅读详情

Item 4: 确保 objects(对象)在使用前被初始化

作者:Scott Meyers

译者:fatalerror99 (iTePub's Nirvana)

发布:http://blog.youkuaiyun.com/fatalerror99/

C++ 看上去在对象的值的初始化方面变化莫测。例如,如果你这样做,

int x;

在某些情形下,x 会被初始化(为 0),但是在其它情形下,也可能没有。如果你这样做,

class Point {
  int x, y;
};

...

Point p;

p 的 data members(数据成员)有时会被初始化(为 0),但有时没有。如果你从一个不存在 uninitialized objects(未初始化对象)的语言来到 C++,请注意这个问题,因为它非常重要。

读取一个 uninitialized values(未初始化值)会引起 undefined behavior(未定义行为)。在一些平台上,读一个 uninitialized value(未初始化值)会引起程序中止,更可能的情况是得到一个你所读的那个位置上的 semi-random bits(半随机二进制位),最终导致不可预测的程序行为和恼人的调试。

现在,有一些描述关于什么时候能保证 object initialization(对象初始化)会发生什么时候不能保证的规则。不幸的是,这些规则很复杂——我觉得它复杂得无法记住。通常,如果你使用 C++ 的 C 部分(参见 Item 1),而且 initialization(初始化)可能会花费一些运行时间,它就不能保证发生。如果你使用 C++ 的 non-C 部分,事情会有些变化。这就是为什么一个 array(数组)(来自 C++ 的 C 部分)不能确保它的元素被初始化,但是一个 vector(来自 C++ 的 STL 部分)就能够确保。

处理这种事情的表面不确定状态的最好方法就是总是在使用之前初始化你的对象。对于 built-in types(内建类型)的 non-member objects(非成员对象),需要你手动做这件事。例如:

int x = 0;                                // manual initialization of an int

const char * text = "A C-style string";   // manual initialization of a
                                          // pointer (see also Item 3)

double d;                                 // "initialization" by reading from

std::cin >> d;                            // an input stream

除此之外的几乎全部情况,initialization(初始化)的重任就落到了 constructors(构造函数)的身上。这里的规则很简单:确保 all constructors(所有的构造函数)都初始化了 object(对象)中的每一样东西。

这个规则很容易遵守,但重要的是不要把 assignment(赋值)和 initialization(初始化)搞混。考虑下面这个表现一个通讯录条目的 class(类)的 constructor(构造函数):

class PhoneNumber { ... };

class ABEntry {                         // ABEntry = "Address Book Entry"

public:

  ABEntry(const std::string& name, const std::string& address,
          const std::list<PhoneNumber>& phones);

private:

  std::string theName;

  std::string theAddress;

  std::list<PhoneNumber> thePhones;

  int num TimesConsulted;

};

ABEntry::ABEntry(const std::string& name, const std::string& address,
                 const std::list<PhoneNumber>& phones)

{

  theName = name;                       // these are all assignments,

  theAddress = address;                 // not initializations

  thePhones = phones;

  numTimesConsulted = 0;

}

这样做虽然使得 ABEntry objects(对象)具有了你所期待的值,但还不是最好的做法。C++ 的规则规定一个 object(对象)的 data members(数据成员)在进入 constructor(构造函数)的函数体之前被初始化。在 ABEntry 的 constructor(构造函数)内,theName,theAddress 和 thePhones 不是 being initialized(被初始化),而是 being assigned(被赋值)。initialization(初始化)发生得更早——在进入 ABEntry 的 constructor(构造函数)的函数体之前,它们的 default constructors(缺省的构造函数)已经被自动调用。但不包括 numTimesConsulted,因为它是一个 built-in type(内建类型)。不能保证它在被赋值之前被初始化。

一个更好的写 ABEntry constructor(构造函数)的方法是用 member initialization list(成员初始化列表)来代替 assignments(赋值):

ABEntry::ABEntry(const std::string& name, const std::string& address,
                 const std::list<PhoneNumber>& phones)

: theName(name),
  theAddress(address),                  // these are now all initializations
  thePhones(phones),
  numTimesConsulted(0)

{}                                      // the ctor body is now empty

这个 constructor(构造函数)的最终结果和前面那个相同,但是通常它有更高的效率。assignment-based(基于赋值)的版本会首先调用 default constructors(缺省构造函数)初始化 theName,theAddress 和 thePhones,然而很快又在 default-constructed(缺省构造)的值之上赋予新值。那些 default constructions(缺省构造函数)所做的工作被浪费了。而 member initialization list(成员初始化列表)的方法避免了这个问题,因为 initialization list(初始化列表)中的 arguments(参数)就可以作为各种 data members(数据成员)的 constructor(构造函数)所使用的 arguments(参数)。在这种情况下,theName 从 name 中 copy-constructed(拷贝构造),theAddress 从 address 中 copy-constructed(拷贝构造),thePhones 从 phones 中 copy-constructed(拷贝构造)。对于大多数类型来说,只调用一次 copy constructor(拷贝构造函数)的效率比先调用一次 default constructor(缺省构造函数)再调用一次 copy assignment operator(拷贝赋值运算符)的效率要高(有时会高很多)。

对于 numTimesConsulted 这样的 built-in type(内建类型)的 objects(对象),initialization(初始化)和 assignment(赋值)没有什么不同,但为了统一性,最好是经由 member initialization(成员初始化)来 initialize(初始化)每一件东西。类似地,当你只想 default-construct(缺省构造)一个 data member(数据成员)时也可以使用 member initialization list(成员初始化列表),只是不必指定 initialization argument(初始化参数)而已。例如,如果 ABEntry 有一个不取得 parameters(参数)的 constructor(构造函数),它可以像这样实现:

ABEntry::ABEntry()
:theName(),                         // call theName's default ctor;
 theAddress(),                      // do the same for theAddress;
 thePhones(),                       // and for thePhones;
 numTimesConsulted(0)               // but explicitly initialize

{}                                  // numTimesConsulted to zero

因为对于那些在 member initialization list(成员初始化列表)中的,没有 initializers(初始化器)的,user-defined types(用户自定义类型)的 data members(数据成员),编译器会自动调用其 default constructors(缺省构造函数),所以一些程序员会认为上面的方法有些过分。这也不难理解,但是一个方针是:在 initialization list(初始化列表)中总是列出每一个 data member(数据成员),这就可以避免一旦发生疏漏就必须回忆起可能是哪一个 data members(数据成员)没有被初始化。例如,因为 numTimesConsulted 是一个 built-in type(内建类型),如果将它从 member initialization list(成员初始化列表)中删除,就为 undefined behavior(未定义行为)打开了方便之门。

有时,即使是 built-in types(内建类型),initialization list(初始化列表)也必须使用。比如,const 或 references(引用)data members(数据成员)是必须 be initialized(被初始化)的,它们不能 be assigned(被赋值)(参见 Item 5)。为了避免记忆什么时候 data members(数据成员)必须在 member initialization list(成员初始化列表)中初始化,而什么时候又是可选的,最简单的方法就是总是使用 initialization list(初始化列表)。它有时是必须的,而且它通常都比 assignments(赋值)更有效率。

很多 classes(类)有多个 constructors(构造函数),而每一个 constructor(构造函数)都有自己的 member initialization list(成员初始化列表)。如果有很多 data members(数据成员)和/或 base classes(基类),成倍增加的 initialization lists(初始化列表)的存在引起令人郁闷的重复(在列表中)和厌烦(在程序员中)。在这种情况下,不能不讲道理地从列表中删除那些 assignment(赋值)和 true initialization(真正的初始化)一样工作的 data members(数据成员)项目,而是将 assignments(赋值)移到一个单独的(当然是 private(私有)的)函数中,以供所有 constructors(构造函数)调用。这个方法对于那些 true initial values(真正的初始值)是从文件中读入或从数据库中检索出来的 data members(数据成员)特别有帮助。然而,通常情况下,true member initialization(真正的成员初始化)(经由一个 initialization list(初始化列表))比经由 assignment(赋值)来进行的 pseudo-initialization(假初始化)更可取。

C++ 并非变幻莫测的方面是一个 object(对象)的数据被初始化的顺序。这个顺序总是相同的:base classes(基类)在 derived classes(派生类)之前被初始化(参见 Item 12),在一个 class(类)内部,data members(数据成员)按照它们被声明的顺序被初始化。例如,在 ABEntry 中,theName 总是首先被初始化,theAddress 是第二个,thePhones 第三,numTimesConsulted 最后。即使它们在 member initialization list(成员初始化列表)中以一种不同的顺序排列(这不幸合法),这依然是成立的。为了避免读者混淆,以及一些模糊不清的行为引起错误的可能性,initialization list(初始化列表)中的 members(成员)的排列顺序应该总是与它们在 class(类)中被声明的顺序保持一致。

一旦处理了 built-in types(内建类型)的 non-member objects(非成员对象)的显式初始化,而且确保你的 constructors(构造函数)使用 member initialization list(成员初始化列表)初始化了它的 base classes(基类)和 data members(数据成员),那就只剩下一件事情需要费心了。那就是——深呼吸先——定义在不同 translation units(转换单元)中的 non-local static objects(非局部静态对象)的 initialization(初始化)的顺序。

让我们一片一片地把这个词组拆开。

一个 static object(静态对象)的生存期是从它创建开始直到程序结束。stack and heap-based objects(基于堆栈的对象)就被排除在外了。包括 global objects(全局对象),objects defined at namespace scope(定义在命名空间范围内的对象),objects declared static inside classes(在类内部声明为静态的对象),objects declared static inside functions(在函数内部声明为静态的对象)和 objects declared static at file scope(在文件范围内被声明为静态的对象)。static objects inside functions(在函数内部的静态对象)以 local static objects(局部静态对象)(因为它局部于函数)为人所知,其它各种 static objects(静态对象)以 non-local static objects(非局部静态对象)为人所知。程序结束时 static objects(静态对象)会自动销毁,也就是当 main 停止执行时会自动调用它们的 destructors(析构函数)。

一个 translation unit(转换单元)是可以形成一个单独的 object file(目标文件)的 source code(源代码)。基本上是一个单独的 source file(源文件),再加上它全部的 #include 文件。

我们关心的问题是这样的:包括至少两个分别编译的 source files(源文件),每一个中都至少包含一个 non-local static object(非局部静态对象)(也就是说,global(全局)的,at namespace scope(命名空间范围)的,static in a class(类内)的或 at file scope(文件范围)的 object(对象))。实际的问题是这样的:如果其中一个 translation unit(转换单元)内的一个 non-local static object(非局部静态对象)的 initialization(初始化)用到另一个 translation unit(转换单元)内的non-local static object(非局部静态对象),它所用到的 object(对象)可能没有被初始化,因为 the relative order of initialization of non-local static objects defined in different translation units is undefined(定义在不同转换单元内的非局部静态对象的初始化的相对顺序是没有定义的)。

一个例子可以帮助我们。假设你有一个 FileSystem class(类),可以使 Internet 上的文件看起来就像在本地。因为你的 class(类)使得世界看起来好像只有一个单独的 file system(文件系统),你可以在 global(全局)或 namespace(命名空间)范围内创建一个专门的 object(对象)来代表这个单独的 file system(文件系统):

class FileSystem {                    // from your library

public:
  ...
  std::size_t numDisks() const;       // one of many member functions
  ...
};

extern FileSystem tfs;                // object for clients to use;
                                      // "tfs" = "the file system"

一个 FileSystem object(对象)绝对是举足轻重的,所以在 tfs object(对象)被创建之前就使用将会损失惨重。(此段和下段原文有误,根据作者网站勘误更改——译者注。)

现在假设一些客户为一个 file system(文件系统)中的目录创建了一个 class(类),他们的 class(类)使用了 tfs object(对象):

class Directory {                       // created by library client

public:

   Directory( params );
  ...
};

Directory::Directory( params )

{
  ...
  std::size_t disks = tfs.numDisks();   // use the tfs object
  ...
}

更进一步,假设这个客户决定为临时文件创建一个单独的 Directory object(对象):

Directory tempDir( params );            // directory for temporary files

现在 initialization order(初始化顺序)的重要性变得明显了:除非 tfs 在 tempDir 之前初始化,否则,tempDir 的 constructor(构造函数)就会在 tfs 被初始化之前试图使用它。但是,tfs 和 tempDir 是被不同的人于不同的时间在不同的 source files(源文件)中创建的——它们是定义在不同 translation units(转换单元)中的 non-local static objects(非局部静态对象)。你怎么能确保 tfs 一定会在 tempDir 之前被初始化呢?

你不能。重申一遍,the relative order of initialization of non-local static objects defined in different translation units is undefined(定义在不同转换单元内的非局部静态对象的初始化的相对顺序是没有定义的)。这是有原因的。决定 non-local static objects(非局部静态对象)的“恰当的”初始化顺序是困难的,非常困难,以至于无法完成。在最常见的形式下——多个 translation units(转换单元)和 non-local static objects(非局部静态对象)通过 implicit template instantiations(隐式模板实例化)产生(这本身可能也是经由 implicit template instantiations(隐式模板实例化)引起的)——不仅不可能确定一个正确的 initialization(初始化)顺序,甚至不值得去寻找可能确定正确顺序的特殊情况。

幸运的是,一个小小的设计改变从根本上解决了这个问题。全部要做的就是将每一个 non-local static object(非局部静态对象)移到它自己的函数中,在那里它被声明为 static(静态)。这些函数返回它所包含的 objects(对象)的引用。客户可以调用这些函数来代替直接涉及那些 objects(对象)。换一种说法,就是用 local static objects(局部静态对象)取代 non-local static objects(非局部静态对象)。(aficionados of design patterns(设计模式迷们)会认出这是 Singleton 模式的通用实现)。(实际上,这只不过是一个 Singleton 实现的一部分。我在这个 Item 中忽略的 Singleton 的核心部分是为了预防创建一个特定类型的多个 objects。)(括号中的文字原文无,参照作者网站勘误添加——译者注。)

这个方法建立在 C++ 保证 local static objects(局部静态对象)的初始化发生在因为调用那个函数而第一次遇到那个 object(对象)的 definition(定义)时候。所以,如果你用调用返回 references to local static objects(局部静态对象的引用)的函数的方法取代直接访问 non-local static objects(非局部静态对象)的方法,你将确保你取回的 references(引用)引向 initialized objects(已初始化的对象)。作为一份额外收获,如果你从不调用这样一个仿效 non-local static object(非局部静态对象)的函数,你就不会付出创建和销毁这个 object(对象)的代价,而一个 true non-local static objects(真正的非局部静态对象)则不会有这样的效果。

以下就是这项技术在 tfs 和 tempDir 上的应用:

class FileSystem { ... };           // as before

FileSystem& tfs()                   // this replaces the tfs object; it could be
{                                   // static in the FileSystem class
  static FileSystem fs;             // define and initialize a local static object
  return fs;                        // return a reference to it
}

class Directory { ... };            // as before

Directory::Directory( params )      // as before, except references to tfs are
{                                   // now to tfs()
  ...
  std::size_t disks = tfs().numDisks();
  ...
}

Directory& tempDir()                // this replaces the tempDir object; it
{                                   // could be static in the Directory class
  static Directory td;              // define/initialize local static object
  return td;                        // return reference to it
}

这个改良系统的客户依然可以按照他们已经习惯的方法编程,只是他们现在应该用 tfs() 和 tempDir() 来代替 tfs 和 tempDir。也就是说,他们应该使用返回 references to objects(对象引用)的函数来代替使用 objects themselves(对象自身)。

按照以下步骤来写 reference-returning functions(返回引用的函数)总是很简单:在第 1 行定义并初始化一个 local static object(局部静态对象),在第 2 行返回它。这样的简单使它们成为 inlining(内联化)的完美的候选者,特别是在它们被频繁调用的时候(参见 Item 30)。在另一方面,这些函数包含 static object(静态对象)的事实使它们在 multithreaded systems(多线程系统)中会出现问题。更进一步,任何种类的 non-const static object(非常量静态对象)—— local(局部)的或 non-local(非局部)的——在 multiple threads(多线程)存在的场合都会发生麻烦。解决这个麻烦的方法之一是在程序的 single-threaded(单线程)的启动部分手动调用所有的 reference-returning functions(返回引用的函数)。以此来避免 initialization-related(与初始化相关)的混乱环境。

当然,用 reference-returning functions(返回引用的函数)来防止 initialization order problems(初始化顺序问题)的想法首先依赖于你的 objects(对象)有一个合理的 initialization order(初始化顺序)。如果你有一个系统,其中 object A 必须在 object B 之前初始化,但是 A 的初始化又依赖于 B 已经被初始化,你将遇到问题,坦白地讲,你遇到大麻烦了。然而,如果你避开了这种病态的境遇,这里描述的方法会很好地为你服务,至少在 single-threaded applications(单线程应用)中是这样。

避免在初始化之前使用 objects(对象),你只需要做三件事。首先,手动初始化 built-in types(内建类型)的 non-member objects(非成员对象)。第二,使用 member initialization lists(成员初始化列表)初始化一个 object(对象)的所有部分。最后,在设计中绕过搞乱定义在分离的 translation units(转换单元)中的 non-local static objects(非局部静态对象)initialization order(初始化顺序)的不确定性。

Things to Remember

  • 手动初始化 built-in type(内建类型)的 objects(对象),因为 C++ 只在某些时候才会自己初始化它们。
  • 在 constructor(构造函数)中,用 member initialization list(成员初始化列表)代替函数体中的 assignment(赋值)。initialization list(初始化列表)中 data members(数据成员)的排列顺序要与它们在 class(类)中被声明的顺序相同。
  • 通过用 local static objects(局部静态对象)代替 non-local static objects(非局部静态对象)来避免跨 translation units(转换单元)的 initialization order problems(初始化顺序问题)。
S/4HANA Private Cloud 与 On-Premise 的 Key User Custom Fields 运输与升级避坑指南 本文探讨了SAP S/4HANA Cloud Private Edition和On-Premise系统中Key User Custom Fields的管理要点。文章指出,Custom Fields涉及元数据生成、对象一致性、传输治理等完整链路,操作不当会导致字段丢失或升级失败。关键建议包括:使用ATO Fiori App管理扩展项与传输绑定,配置正确的job user权限,避免在多系统并行开发同一字段。特别强调升级时需执行CFD_REGENERATE_IN_ONPREMISE报表,并通过标准传输机制推进变更 阅读详情

相关推荐

DeepSeek Harness实战:从零构建插件化AI Agent

AI Agent开发正从硬编码走向框架化组织,插件化架构成为提升工程效率的关键。在构建可复用、可扩展的智能体系统时,开发团队需要一套能够统一管理模型调用、工具注册与上下文组装的基础设施。DeepSeek Harness作为面向Agent工程的插件化框架,通过Harness、DeepAgent与Skill三个核心抽象,将模型、工具与技能解耦为可插拔单元,让开发者无需重复造轮子即可快速搭建具备工具调用能力的智能体。本文从环境配置到Skill插件开发,完整演示如何基于DeepSeek模型构建一个可运行的Agent

weixin_34279184的博客 453

【翁恺】11-初始化列表

cladd Point{ private: const float x,y; Point(float xa =0.0,float ya=0.0):y(ya),x(xa){} }; can initialize any type of data pseudo-constructor calls for built-ins no need to perform assignment within body of constructor order of initial

博观约取,厚积薄发 635

360加固DEX解密与ELF修复技术解析

本文深入解析360加固的DEX解密与ELF修复技术,详细介绍了其多层保护机制、Java层入口分析、Native层加载流程及反调试绕过技巧。通过RC4和zlib解密技术,结合Frida工具实现内存Dump和ELF文件修复,为逆向工程师提供实用解决方案。

weixin_29327525的博客 512

[笔记]Effective C++ 条款4:确定对象被使用前已被初始化

读取未初始化的值会导致不明确的行为。 对于无任何成员的内置类型,必须手动完成初始化。 int x = 0; //对int进行手工初始化 const char* text = "A C-style string"; //对指针进行手工初始化 double d; std::cin >> d; //以读取input stream的方式完成初始化 对于内置类型以外的任何其他东西,则在构造函数中确保每一个成员函数初始化。 区别赋值(assignment)和初始化(init

weixin_42796916的博客 209

数据产品需求文档(PRD)怎么写?阿里P8分享的模板+5个避坑点

作用:记录文档的版本、作者、评审信息,避免“文档混乱”。填写规范字段说明示例文档名称清晰反映产品名称,如“用户行为分析平台PRD”用户行为分析平台PRD_V1.0文档版本用“版本号+日期”,如V1.0_20240301编写人数据产品经理姓名+联系方式张三(138-XXXX-XXXX)评审人员业务负责人、开发经理、数据分析师、运维负责人李四(业务)、王五(开发)、赵六(数据)、周七(运维)评审时间评审日期2024-03-05评审意见。

架构师的AI之路,分享AI应用开发架构的学习与实践。 1575

OAI数据集申请下载全攻略:从个人NDA账号注册到数据包下载的保姆级避坑指南

本文提供OAI数据集申请下载的完整指南,涵盖从个人NDA账号注册到数据包下载的全流程。重点解析login.gov验证陷阱、浏览器兼容性问题、NDA权限申请技巧及nda-tools高效使用方法,帮助医学影像研究者避开常见技术障碍,快速获取全球骨关节炎研究数据库OAI的宝贵数据资源。

weixin_28698059的博客 753

C4700: 使用了未初始化的局部变量“s”

PAT1044 #include<iostream> using namespace std; #include<string> int main() { //这里如果写作:char* s; //cin.get函数会报错:s为初始化 //C4700: 使用了未初始化的局部变量“s” //这是c++的重要准则,凡指针被使用,必先初始化指针 //将其改成char s[50];后,就给指针型变量s一个初始化的机会, //类似数组初始化与指针类型数组声明区别,给定具体容量大小

qq_45949701的博客 1万+

从零开始学习CANoe(六)—— CAPL 测试节点

创建CAPL Test Module的两种方式

蚂蚁小兵 1万+

确保 objects(对象)在使用前被初始化

     C++ 看上去在对象的值的初始化方面变化莫测。例如,如果你这样做,int x;    在某些情形下,x 会被初始化(为 0),但是在其它情形下,也可能没有。如果你这样做,class Point {  int x, y;};...Point p;     p 的 data members(数据成员)有时会被初始化(为 0),但有时没有。如果你从一个不存在

cameracanon的专栏 2392

全面解析 SAP 事务码 LTMOM 的应用与实践

综上所述,事务码 LTMOM 是 SAP 系统中不可或缺的迁移对象维护工具,它不仅提供了对数据迁移对象的精细配置功能,还通过灵活的数据转换规则与异常监控机制,为企业数据从 SAP ERP 向 SAP S/4HANA 的迁移提供了坚实保障。在数据迁移过程中,并非所有的迁移对象都需要同时启用。业内专家普遍认为,未来的系统升级与数据迁移将更注重业务需求的动态变化与数据实时性的要求,而 LTMOM 作为核心工具,其在流程自动化、数据智能校验以及跨系统数据联动方面的能力,将直接影响企业整体数字化转型的成败。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1013

基于imx6ull平台opencv的图像采集、ffmpeg推流和Windows端拉流(多线程)

本文档是针对imx6ull平台`opencv`的图像采集、ffmpeg推流和Windows端拉流。首先创建一个线程`opencv`通过摄像头采集视频图像,接着再创建两个线程,其中一个线程获取采集的视频图像送给ffmpeg服务,另一个线程用于获取采集的视频图像并处理,处理完并在显示屏上显示,详细的流程请参看如下。

程小二的博客 1607

C++人该知道的N个问题与做法:确保对象被使用前已先初始化

前言: int n; 在某些语境下x可以保证被初始化(为0),但在其他语境中却不保证。如果你这么写: class Point { int x,y; }; ... Point p; p的成员变量有时候被初始化(为0),有时候不会,如果你是其他某些语言,并不存在“无初值对象”,那么请小心,因为这颇为重要。 有些平台读取未初始化的值会使程序终止运行,但大多数情况下是读入一些随机的数据,污染程序对象,导致不可预测的程序行为,以及许多令人不愉快的调试过程,如果是业务相关,那麻烦就大了。 初始

lzzw的学习之路 390

全志 camera: 4路AHD摄像头转MIPI

TP2815 驱动模块主要实现将 4 路的 AHD/TVI/CVBS Camera 的数据转换为 MIPI 数据,从而实现在 T527 端来对数据进行处理和送显。

Linux驱动开发工程师,熟悉Linux/Android底层驱动、TP、显示、IIC、网络等通用外设调试适配,Linux上层应用开发。常用平台瑞芯微、全志、恩智浦等。 9098

博客摘录「 [翻译] Effective C++, 3rd Edition, Item 4: 确保 objects(对象)在使用前被初始化」2025年2月27日

initialization list(初始化列表)中 data members(数据成员)的排列顺序要与它们在 class(类)中被声明的顺序相同。通过用 local static objects(局部静态对象)代替 non-local static objects(非局部静态对象)来避免跨 translation units(转换单元)的 initialization order problems(初始化顺序问题)。

qq_44644334的博客 380

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

不要浪费构造函数的时间

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 欢迎使用Markdown编辑器 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Mar

q351477的博客 348

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

条款04(一):确定对象被使用前已经被初始化

将对象初始化,内置类型的初始化,构造函数的初始化,赋值&amp;初始化的区别

不积跬步无以至千里 431

精雕软件(JDpaint) 5.5 绿色版

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

[c++基础] 类的四个基本函数

1.面向对象的基本概念 所谓面向过程的编程思想,就是分析解决问题的步骤,将这些步骤用一个个函数实现,最后一个个调用。 所谓面向对象的编程思想,就是将任何事物都看成一个对象,对象有各种属性(attribute)和行为(behavior),在解决问题的过程中,将系统分解,使之模块化。 优势:可维护性,可扩展性,可复用性 面向对象的程序设计有四个主要特点:抽象、封装、继承、多态。

qq_26304333的博客 4228

Effective C++ (第4项:确保对象在使用前得到初始化)

第4项:    确保对象在使用前得到初始化 C++ 在对象初始值问题上显得变化多端。比如说,你写下了下面的代码: int x; 在许多情况下, x 会确保得到初始化(为零),但是另一些情况下则不会,如果你这样编写: class Point {   int x, y; }; ... Point p; p 的数据成员在一些情况下会确保得到初始化(为零

Tony's Blog 1022

Effective C++ 学习笔记 《四》

Item 4: Make sure that objects are initialized before they’re used 这一节谈论的就是C++的初始化问题。这也是学习C++的时候容易犯错的地方。 比如下面这段代码,类Point中的x和y就是未初始化的,所以打印得到的值是没有意义的。 class Point { public: inline int getx() { retur...

Teee 195

12.18

Effective C++ Scott Meyers   Chapter 1. Uses and Abuses of vector 1. Item 4: Make sure that objects are initialized before they're used.   Use member initialization list to initialize the member. ...

weixin_30548917的博客 144

C++对象初始化

#ifndef TDATE_H_INCLUDED #define TDATE_H_INCLUDED #include&amp;amp;lt;iostream&amp;amp;gt; class TDate{ public: TDate(int y,int m,int d); ~TDate(); void Print(); private: int year,month,day; }; //构造...

紫芝的博客 1566

Order of initialization

Order of initialization Within a class, the order of initialization is determined by the order that the variables are defined within the class. The variable definitions may be scattered throughout an

sutonline的博客 526

C++11 Object初始化问题

C++11 中 类实例的初始化问题比较复杂。 这里涉及到实例的类型, (static vs non-static), 有没有自定义构造函数等等。对于static类型(全局变量,namespace变量,类static数据成员,函数static局部成员),class内部的成员变量都会使用默认值初始化. //Struct S1 w/o constructor struct S1 {

techx的专栏 690

C++之对象初始化详解

对象在创建时获得了一个特定的值,我们说这个对象被初始化。初始化不是赋值,初始化的含义是创建变量赋 予其一个初始值,而赋值的含义是把当前值擦除,而以一个新值来替代。 默认初始化:         如果定义变量时没有指定初值,则变量被默认初始化,此时变量被赋予了“默认值”         1、如果是内置类型的变量且未被显示初始化,它的值由位置决定。定义在任何函数体之外的变量被初始化

Bruce_0712的博客 3274

重读经典-《Effective C++》Item4:确定对象被使用前已先被初始化

1. 永远在使用对象之前先将它初始化 (1) 对于无任何成员的内置类型,须手工进行初始化。 如: int x = 0; Const char* text = "A C-style string"; Double d; Std::cin >> d; //以读取input stream的方式完成初始化 (2) 对于内置类型意外的任何其他东西,初始化由构造函数函数完成。 规则1:确保每一个构造函数都将对象的每一个成员初始化。 注意:别混淆了赋值(assignment)和初始化(init

学习,思考,记录,分享。 2920

Thinking in Java [Java编程机制] 学习笔记 -- 初始化顺序Order of initialization

首先 初始化的顺序和变量声明的顺序有关,并且变量(包括primitive types and object reference)的初始化一定是在所有方法被调用之前,甚至constructor也要在此之后。 静态数据初始化 static data initialization 所有的静态数据都存储在一片存储区中,初始化也只会进行一次。初始化顺序是这样的:1.static(如果已经初始化

My World 1348
上一篇: [翻译] Effective C++, 3rd Edition, Item 3: 只要可能就用 const
下一篇: [翻译] Effective C++, 3rd Edition, Item 5: 了解 C++ 为你偷偷地加上和调用了什么函数
fatalerror99
博客等级 码龄24年 166粉丝 20原创
评论 13
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值