营销网站是什么意思,网站建设时关键词要怎么选呢,北京建站设计,建设简单网站的图纸实现
条款26#xff1a;尽可能延后变量定义式的出现时间
条款27#xff1a;尽量少做转型动作
条款28#xff1a;避免返回handles指向对象内部成分
在C中#xff0c;handles是指一个指向对象的指针或引用#xff0c;用于访问该对象的成员函数或成员变量。
而条款28所说…实现
条款26尽可能延后变量定义式的出现时间
条款27尽量少做转型动作
条款28避免返回handles指向对象内部成分
在C中handles是指一个指向对象的指针或引用用于访问该对象的成员函数或成员变量。
而条款28所说的“返回handles指向对象内部成分”是指返回指向该对象的私有成员或受保护成员的指针或引用。
这样做的问题在于如果对该成员进行修改或者删除操作可能会破坏该对象的不变量invariant或者类的封装性导致程序出现不可预测的结果。
另外如果返回的指针或引用是指向临时对象或已经被释放的对象则会导致指针悬挂dangling pointer或引用无效的问题。
为了避免这种问题建议使用对象的公有成员函数访问该对象的内部成分而不是返回指向内部成分的指针或引用。
如果必须返回指针或引用可以考虑使用智能指针如std::shared_ptr或std::unique_ptr来确保对象的生命周期或者返回const指针或引用防止被修改。
假设有一个类Person其中有一个私有变量age表示年龄如下所示
class Person {
public:void SetAge(int age) { this-age age; } // 设置年龄int GetAge() const { return age; } // 获取年龄
private:int age;
};如果在该类中返回对age的引用或指针就会存在返回handles指向对象内部成分的问题。例如
const int GetAgeRef() const { return age; } // 返回对age的引用
const int* GetAgePtr() const { return age; } // 返回指向age的指针在这种情况下如果返回的引用或指针被用于修改或者删除age将会破坏Person类的封装性导致程序出现不可预测的结果。 为了解决这个问题可以使用对象的公有成员函数访问该对象的内部成分而不是返回指向内部成分的指针或引用。例如
class Person {
public:void SetAge(int age) { this-age age; } // 设置年龄int GetAge() const { return age; } // 获取年龄void SetAgeViaFunction(int age) { SetAge(age); } // 通过公有成员函数设置年龄
private:int age;
};在这个例子中我们新增了一个公有成员函数SetAgeViaFunction用于通过公有成员函数SetAge来设置年龄。这样外部代码就不能直接访问age而是必须通过SetAgeViaFunction来访问age从而保证了Person类的封装性。
条款29为“异常安全”而努力是值得的 “异常安全”是指程序在面对异常时能够保持正确性、资源不泄漏、不破坏数据结构等性质。 在C中异常安全是非常重要的因为C支持异常机制如果程序无法正确处理异常可能会导致资源泄漏、内存泄漏、数据结构损坏等问题从而影响程序的正确性和稳定性。 请记住
异常安全函数Exception-safe functions即使发生异常也不会泄露资源或允许任何数据结构败坏。这样的函数区分为三种可能的保证基本型、强烈型、不抛异常型。“强烈保证”往往能够以 copy-and-swap 实现出来但“强烈保证“并非对所有函数都可实现或具备现实意义。函数提供的”异常安全保证“通常最高只等于其所调用的各个函数的”异常安全保证“中的最弱者。
因此为了确保程序的异常安全性我们需要在编写代码时考虑并努力实现异常安全。具体来说我们需要注意以下几点 确保不会让异常逃逸在函数中抛出异常后应该确保异常被正确地处理掉而不是让它逃逸到函数外部导致资源泄漏或数据结构损坏。为了避免异常逃逸可以使用RAII技术通过在对象构造函数中获取资源在对象析构函数中释放资源来保证资源的正确获取和释放。 考虑异常安全的级别异常安全性有三个级别分别是基本保证、弱异常安全和强异常安全。在编写代码时应该根据情况选择最佳的异常安全级别。 基本保证是指如果函数出现异常程序状态不会受到破坏但是可能会发生资源泄漏。 弱异常安全是指如果函数出现异常程序状态和资源都不会受到破坏但是可能会出现不一致的状态。 强异常安全是指如果函数出现异常程序状态和资源都不会受到破坏而且程序状态和资源都会回到调用函数前的状态。 使用异常处理机制在编写代码时应该使用异常处理机制来处理异常。通过抛出异常并捕获异常可以避免程序崩溃并将异常抛出给调用者进行处理。在抛出异常时应该提供一个清晰的异常信息方便调用者进行处理。
条款30透彻了解inlining的里里外外
条款30中的inlining是指C中的内联函数它是一种编译器的优化技术可以将函数调用处直接替换为函数体从而减少函数调用的开销提高程序的性能。但是内联函数也有一些限制和缺点因此在使用内联函数时需要透彻了解其里里外外以便能够正确地使用和优化内联函数。
具体来说理解inlining的里里外外需要注意以下几点
内联函数的适用范围内联函数适用于函数体比较小、被频繁调用的函数。如果函数体比较大内联函数可能会导致代码膨胀从而影响程序的性能。因此在使用内联函数时需要根据实际情况进行选择。内联函数的定义内联函数通常需要在头文件中进行定义以便编译器能够在编译时进行函数替换。在定义内联函数时需要注意函数体不能包含循环、递归等语句否则会导致编译器无法进行内联。内联函数的声明内联函数的声明通常也需要在头文件中进行以便其他文件能够调用内联函数。**在声明内联函数时需要使用inline关键字**以便告诉编译器该函数需要进行内联。内联函数的优化在使用内联函数时需要注意优化内联函数的代码以提高程序的性能。可以使用一些技巧如避免多余的函数调用、避免局部变量过多、使用常量表达式等。内联函数的限制内联函数也有一些限制例如不能取地址、不能有静态变量等。在使用内联函数时需要注意这些限制以便正确地使用内联函数。
请记住
将大多数inlining限制在小型、被频繁调用的函数身上。这可使日后的调试过程和二进制升级更容易也可使潜在的代码膨胀问题最小化使程序的速度提升机会最大化。不要只因为function templates 出现在头文件就将它们声明为inline 如何理解“不要只因为function templates 出现在头文件就将它们声明为inline”这句话 在C中函数模板function templates是一种通用的函数定义方式它可以用来定义多个具有相同功能但类型不同的函数。**由于函数模板通常需要在头文件中进行定义因此很容易将它们声明为内联函数inline以提高程序的性能。**但是在使用函数模板时不要只因为它们出现在头文件中就将它们声明为内联函数而应该根据实际情况进行选择。 具体来说不要将所有函数模板都声明为内联函数的原因有以下几点
函数模板的大小不确定由于函数模板可以用于定义多个函数因此其大小在编译时是不确定的。如果将所有函数模板都声明为内联函数可能会导致代码膨胀从而影响程序的性能。内联函数的适用范围有限内联函数适用于函数体比较小、被频繁调用的函数。对于函数模板来说其具体调用情况是不确定的因此并不是所有函数模板都适合声明为内联函数。其他优化方式除了将函数模板声明为内联函数之外还有其他一些优化方式如使用编译器的优化选项、避免多余的函数调用等。在使用函数模板时应该根据实际情况选择最合适的优化方式。
因此不要只因为函数模板出现在头文件中就将它们声明为内联函数。应该根据实际情况进行选择综合考虑函数模板的大小、调用情况、优化方式等因素以便选取最合适的优化方案。 如何理解“将大多数inlining限制在小型、被频繁调用的函数身上。这可使日后的调试过程和二进制升级更容易也可使潜在的代码膨胀问题最小化使程序的速度提升机会最大化。”这句话 这句话指出了在使用内联函数时应该将大多数内联函数限制在小型、被频繁调用的函数中以便最大化程序的速度提升机会并最小化潜在的代码膨胀问题同时也方便了日后的调试过程和二进制升级。 具体来说这句话的含义可以从以下几个方面进行解释
内联函数的适用范围内联函数适用于函数体比较小、被频繁调用的函数。将大多数内联函数限制在这样的函数中可以最大化程序的速度提升机会因为内联函数可以减少函数调用的开销。调试和升级的问题将内联函数限制在小型、被频繁调用的函数中可以使调试过程更加容易因为这些函数的代码比较简单容易定位和排查问题。同时也方便了二进制升级因为这些函数的代码不会对其他部分的代码产生过多的影响。代码膨胀问题内联函数会将函数体直接嵌入到调用处从而增加代码的长度。如果将所有函数都声明为内联函数可能会导致代码膨胀从而影响程序的性能。将大多数内联函数限制在小型、被频繁调用的函数中可以最小化潜在的代码膨胀问题并提高程序的性能。
综上所述将大多数内联函数限制在小型、被频繁调用的函数中可以最大化程序的速度提升机会最小化潜在的代码膨胀问题并方便了日后的调试过程和二进制升级。
条款31将文件间的编译依存关系降至最低
条款31指出了在软件开发中应该尽可能地将文件间的编译依存关系降至最低以便实现更好的模块化和可重用性。具体来说可以从以下几个方面来理解这个条款 编译依存关系文件间的编译依存关系指的是一个源文件或头文件在编译时所依赖的其他源文件或头文件。如果一个源文件依赖于另外的源文件那么在编译时就需要将这些源文件一起编译从而增加了编译时间和编译的复杂性。 最小化编译依存关系的好处将文件间的编译依存关系降至最低可以实现更好的模块化和可重用性。 模块化指的是将软件系统分解为多个独立的模块每个模块都具有清晰的接口和功能 可重用性指的是可以将一个模块在不同的系统中重复使用。 最小化编译依存关系可以使得每个模块都具有清晰的接口和功能从而提高了模块化和可重用性。 实现最小化编译依存关系的方法实现最小化编译依存关系的方法有很多比如使用前置声明forward declaration、将接口和实现分离、使用接口类interface class等。 前置声明可以减少头文件之间的相互依赖将接口和实现分离可以使得模块之间的依赖更加清晰 使用接口类可以将模块之间的依赖限制在接口上从而提高了模块化和可重用性。
以下是对该条款的理解和一些实践建议 减少头文件的依赖尽量减少头文件之间的相互包含只包含必要的头文件。这样可以降低编译依存关系避免引入不必要的依赖关系。 使用前向声明Forward Declaration如果在头文件中只需要使用某个类的指针或引用而不需要知道其具体实现细节可以使用前向声明来代替包含整个头文件。这样可以减少头文件的依赖关系。 使用接口类Interface Class将公共接口定义在一个独立的接口类中然后在其他文件中使用该接口类而不是具体的实现类。这样可以降低对具体实现类的依赖提高代码的可扩展性和可替换性。 使用编译器前置声明Compiler Firewall在某个实现文件中使用前向声明和指针/引用然后在该文件的头文件中包含所需的具体实现。这样可以将依赖关系局限在该实现文件内部减少对其他文件的影响。 使用纯虚函数Pure Virtual Functions如果某个类在其他文件中只需要通过指针或引用进行操作可以将该类设计为纯虚函数的基类然后使用基类的指针或引用来操作具体的子类。这样可以降低对具体子类的依赖提高代码的灵活性和可扩展性。
总的来说条款31的目标是通过降低文件间的编译依存关系减少代码间的耦合性从而提高代码的可维护性和可扩展性。通过合理的头文件设计、前向声明、接口类和编译器前置声明等技术手段可以将依赖关系限制在合适的范围内使代码更加模块化、可重用和易于维护。