![](https://img-blog.csdnimg.cn/20201014180756923.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
effective C++
^卿^
他日若是凌云志,敢笑黄巢不丈夫
展开
-
Effective C++ 条款31 将文件间的编译依存关系降至最低
一、文件间的编译依存性****1.现象: 假设你对C++程序的某个class实现文件做了些轻微的修改。(而且,这里修改的并不是class接口,而是实现,而且只改private成分。然后重新建置这个程序,你会发现所有的东西都需要重新编译和连接。2.原因:问题出在C++并没有把"将接口从实现中分离"做的很好。Class的定义式不只详细叙述了class接口,还包括十足的实现细目。例如:class Person {public: Person(const std::string& n转载 2020-12-08 00:04:06 · 214 阅读 · 0 评论 -
Effective C++ 条款30 透彻了解inlining的里里外外
1.inline 的优缺点> 优点——看起来像函数——动作像函数——比宏好很多——可以调用它们又不需要蒙受函数调用所招致的额外开销——编译器最优化机制通常被设计用来浓缩那些“不含函数调用”的代码,所以当你inline某个函数,或许编译器就因此——有能力对它(函数本体)执行预警相关最优化。大部分的编译器不会对一个“outlined函数调用”动作执行如此之最优化> 缺点——可能增加目标码(object code)的大小——inline造成的代码膨胀会导致额外的换页行为,降低指令告诉转载 2020-12-07 23:21:26 · 172 阅读 · 0 评论 -
Effective C++ 条款28 避免返回handles指向对象内部成分
假设我们的程序涉及矩形。每个矩形由其左上角和右下角表示。为了让一个Rectangle对象尽可能小,你可能会决定不把定义矩形的这些点放在Rectangle对象内,而是放在一个辅助的struct内再让Rectangle去指它:class Point { // 描述点 的类public:Point( int x ,int y );…void setX(intnewVal);void setY(intnewVal);…};struct RectData { //用这些”转载 2020-12-07 23:04:25 · 226 阅读 · 0 评论 -
Effective C++ 条款27 尽量少做转型动作
1.一些基础C++规则的设计目标之一 —— 保证“类型错误” 绝对 不可能发生。理论上,如果程序很"干净地"通过编译,就表示它并不企图在任何对象身上执行任何不安全、无意义、愚蠢荒谬的操作。But,转型(cast)破坏了类型系统(type system),这种可能会导致任何种类的麻烦,而且这些麻烦繁琐度不一。如果你用的是C、Java 或 C# ,这点就需要特别注意一下,因为那些语言中的转型比较必要而无法避免,与C++相对比较而言,也不是特别危险。关于转型(cast),这里通常有三种不同的形式:( 都原创 2020-12-07 22:55:50 · 129 阅读 · 0 评论 -
Effective C++ 条款26 尽可能延后变量定义式的出现
1.原因?只要我们定义了一个变量而且这个类型有一个构造函数或析构函数,那么,我们的程序到达这个变量的定义式时,就不得不承受构造的成本,当我们的变量离开作用域时,就要承担析构的成本。即使这个变量没有被使用。总结起来一句话——太快定义变量可能造成效率上的拖延。2.疑问<1> 万一我认定我不可能定义一个不使用的变量呢?看下这个函数:std::string encryptPassword( const std::string& password ){ using names转载 2020-12-07 21:59:00 · 406 阅读 · 0 评论 -
Effective C++条款 22 - 24
条款22:将成员变量声明为private讲解这个条款的思路是,首先看看成员变量为什么不应该是public,这个观点同样适用于protected成员变量,最后得出结论:成员变量应该是private。首先从语法一致性开始(条款18),如果成员变量不是public,那么客户访问该成员的唯一方法就是通过成员函数(如果没有友函数)。如果public接口内的每样东西都是函数,客户在使用这个对象时,就不需要疑问到底是访问变量还是函数了,因为这个时候不能访问成员变量。或许一致性不是令你信服的理由。还有一个理由:使用函原创 2020-12-03 19:52:16 · 266 阅读 · 0 评论 -
Effective C++ 条款20-21
条款20 宁以pass-by-reference-to-const替换pass-by-value此条款本应就很熟悉,值得记住作者给予的两条忠告:i、尽量以pass-by-reference-to-const替换pass-by-value。前者通常比较高效,并可避免切割问题(也就是多态的实际运用)。ii、上述条款并不适用于内置类型,以及STL的迭代器和函数对象。对它们而言,pass-by-value往往比较适当。以下举例验证上述条款:class Person {public: Person();原创 2020-12-03 19:50:49 · 119 阅读 · 0 评论 -
Effective C++ 设计class犹如设计type
C++就像在其他OOP(面向对象编程)语言一样,当你定义一个新的class,也就定义了一个新type。作为一个C++程序员,你的许多时间主要用来扩展你的类。也就意味着,你不仅仅是个class设计者,依旧是一个type设计者。所以你要谨慎对待class设计。这个条款,主要就是讲述如何设计高效的class,为此,本书提供了一系列条款。*▪ 新type的对象应该如何被创建和销毁?*这会影响你的class构造函数和析构函数以及内存分配函数和释放函数的设计。▪ 对象的初始化和对象的赋值该有什么样的差别?这决原创 2020-12-03 19:50:04 · 95 阅读 · 0 评论 -
Effective C++ 让接口容易被正确使用,不易被误用
如题目,我们自己的程序接口是面向用户的,程序的目的不可是解决这个问题,并且要让用户easy使用。所以。必须保证我们的程序接口具有非常强的健壮性。怎么保证接口的健壮性,不同情况有不同的处理结果,作者列出了以下几个样例所相应的方法。1.设计一个class来表示日期class Date{public: void Date(int month, int day, int year); ……};12345以上的构造接口非常easy被用户用错Date d(30, 3, 1995);//把月和日弄原创 2020-12-03 19:48:55 · 83 阅读 · 0 评论 -
effective c++ 条款16-17:以独立语句将new对象置入智能指针
条款16:成对使用new和delete时要使用相同形式其实这一条款十分简单,只需要记住即可,没啥特别的点需要说的。在我们使用 new 创建对象时,就应该使用 delete 删除对象;在使用 new[] 创建对象时,应该对于地使用 delete[] 进行删除。在使用new时会做两件事: 1、内存被分配出来 2、针对内存会有一个(或更多)的构造函数被调用在使用delete时也做两件事:原创 2020-12-01 13:37:11 · 94 阅读 · 0 评论 -
effective c++ 条款15:在资源管理类中提供对原始资源的访问
记住:APIs往往要求访问原始资源,所以每一个RAII类应该提供一个“取得其所管理之资源”的办法。对原始资源的访问可能经由显示转换或隐式转换。一般而言显示转换比较安全,但隐式转换对客户比较方便。std::tr1::shared_ptr<Investment> pInv(createInvestment());int daysHeld(const Investment* pi);int days = daysHeld(pInv); //错误int days = daysHeld原创 2020-12-01 13:36:08 · 91 阅读 · 0 评论 -
Effective C++ 条款14 在资源管理器中小心copying行为
条款13导入RAII的观念:资源获取时机便是初始化时机,资源会在不需要的时刻被销毁,典型代表就是shared_ptr和weak_ptr,但是并非所有资源都是堆内存,例如外存和堆栈,在这种情况下,auto_ptr,shared_ptr,weak_ptr显然不适合作为资源管理类,这就需要建立自己的资源管理类同样,自建的资源管理类同样需要考虑RAII对象被复制的问题,一般有以下两种选择:禁止复制:将copying声明为private且不提供定义,或者继承自一个将copying函数声明为private的基类.原创 2020-12-01 13:34:54 · 102 阅读 · 0 评论 -
Effective C++ 条款十三 以对象管理资源
现在假设用一个类来模拟投资行为,各式各样的投资类都继承自一个基类Investment。class Investment{...}; //基类用工厂函数来创建特定的Investment对象:Investment* createInvestment();createInvestment的调用端使用了函数返回的对象之后,有责任删除之,如下函数履行了这个责任:void f(){ Investment* pInv=createInvestment(); ... delete pInv;//原创 2020-12-01 13:33:29 · 59 阅读 · 0 评论 -
Effective C++ 条款十二:复制对象时勿忘其每一个成分
这句话包含两部分的意思:第一部分是要考虑到所有成员变量,特别是后加入的,相应的拷贝构造函数和赋值运算符要及时更新;第二部分是在存在继承时,不要遗忘基类部分的复制。先看第一部分的意思,举个例子:class SampleClass{private: int a;public: SampleClass(const SampleClass& s):a(s.a) {}};这里只举了一个拷贝构造函数的例子,赋值运算符与之类似,如果这个时候又加了转载 2020-11-27 22:19:24 · 160 阅读 · 1 评论 -
Effective C++ 条款十一:在operator=中处理自我赋值
直观的operator=是这样定义的:class SampleClass{private: int a; double b; float* p;public: SampleClass& operator= (const SampleClass& s) { a = s.a; b = s.b; p = s.p; return *this; }};就是将自身的私有成员的值全转载 2020-11-27 22:14:48 · 81 阅读 · 0 评论 -
Effective C++ 条款十一:在operator=中处理自我赋值
直观的operator=是这样定义的: 1 class SampleClass 2 { 3 private: 4 int a; 5 double b; 6 float* p; 7 public: 8 SampleClass& operator= (const SampleClass& s) 9 {10 a = s.a;11转载 2020-11-27 22:09:57 · 169 阅读 · 0 评论 -
令operator=返回对象的引用
为什么返回引用为了支持连锁赋值返回引用可以节省资源,不必要为返回值调用构造函数了什么是连锁赋值int x,y,z;x = y = z = 5;这种赋值方式称为连锁赋值,它满足右结合律x = ( y = ( z = 5 ));赋值表达式z = 5执行后,将更新后的z值赋值给y,以此类推。自定义类型的连锁赋值Widget m;...Widget x, y, z;x = y = z = m;为了支持这种连锁赋值,z = m执行后,必须返回Widget类型的对象或该类型对象的原创 2020-11-27 22:08:39 · 215 阅读 · 0 评论 -
Effective c++学习笔记——条款09:绝不在构造和析构过程中调用virtual函数
Never call virtual functions during construction or destruction 这是本条款的核心,不该在构造函数和析构函数期间调用virtual函数,因为存在不可预期的结果。为什么会这么说呢?首先看一下下面的例子:// never_call_vir.cpp : 定义控制台应用程序的入口点。 //2011/9/10 by wallwind #include "stdafx.h" #include <iostre...转载 2020-11-26 22:15:53 · 227 阅读 · 0 评论 -
Effective C++条款07:为多态基类声明virtual析构函数
显而易见,这个条款和多态的这个特性息息相关。多态的其中一个重要是通过我们在基类中的声明虚函数,子类进行重写(override)。那么在基类中,我们声明了虚函数或者纯虚函数,那么我们应该对应地就要有虚析构函数,但是往往我们会忽略这个问题,这就会导致严重的内存泄漏问题。下面我们上代码:class base //这里的基类并没有声明虚析构函数{ public: base() { std::cout<<"creating base class!"<<s.转载 2020-11-26 22:09:13 · 114 阅读 · 0 评论 -
C++笔记 06:若不想使用编译器自动生成的函数,就该明确拒绝
Effective C++笔记Explicitly disallow the use of compiler-generated functions you do not want将连接期错误移至编译器是可能的总结原创 2020-11-26 22:05:10 · 58 阅读 · 0 评论 -
Effective C++条款五:C++默认编写了哪些函数
几乎每一个类都会用到构造、析构和赋值方法。C++默认编写了哪些函数拷贝构造函数 赋值操作符 析构函数 默认构造函数(如果你没有声明任何构造函数)编译器默默添加的这些函数都是public inline的。默认构造函数,有两个职责调用基类的构造函数 调用non-static成员变量的构造函数析构函数,也有两个职责调用基类的析构函数 调用non-static成员变量的析构函数拷贝构造函数和赋值操作符将源对象的每一个non static成员变量拷贝给目标对象注意:如果代转载 2020-11-26 22:02:27 · 121 阅读 · 0 评论 -
effective c++ 条款04:确定对象被使用前已先被初始化
危害:读取未初始化的值会导致不明确甚至是半随机化的行为。最佳处理办法:永远在使用对象之前先将它初始化;确保每一个构造函数都将对象的每一个成员初始化。1 注意区分赋值和初始化:从初始化的角度而言,这不是一个最佳的处理办法。虽然这会让对象的指最终为你期望的值,但是实际上,对象的成员变量的初始化动作发生在进入构造函数本体之前。而在构造函数本体之内,不是被初始化,而是被赋值。2 较佳的写法:使用成员变量初始化列表结果和上一个的最终结果相同,但是效率较...转载 2020-11-26 15:21:13 · 92 阅读 · 0 评论 -
c++ const 全面总结
C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方面查到的资料进行总结如下,期望对朋友们有所帮助。Const是C++中常用的类型修饰符,常类型是指使用类型修饰符const说明的类型,常类型的变量或对象的值是不能被更新的。一、Const作用如下表所示: No. 作用 说明 参考代码 1 可以定义c...转载 2020-11-26 14:24:35 · 216 阅读 · 0 评论