条款26:尽可能延后变量定义式的出现时间

  • C++推荐在使用对象前才定义对象(调用构造函数赋初值)
  • 只在循环中使用的变量定义在循环内部(除非"赋值"成本低于"构造+析构"成本)

条款27:尽量少做转型动作

  • 旧式风格转型

    • C风格转型 \((T)expression\)
    • 函数风格转型 \(T(expression)\)
  • C++四种新式转型(new-style 或 C++-style cases)
    • const_cast(expression) 移除对象常量性(cast away the constness)
    • dynamic_cast(expression) 安全向下转型(safe downcasing)
    • reinterpret_cast(expression) 低级转型
    • static_cast(expression) 强迫隐式转型(implicit conversions)
  • 尽量避免转型(特别是dynamic_cast)
#include <iostream>
#include <string>
#include <memory> using namespace std; class base {
public:
virtual void type() {cout << "base" << endl;}
}; class drive : public base {
public:
drive( double d) : dou(d) {}
virtual void type() {cout << "drive" << endl;} void show() {
cout << dou << endl;
} private:
double dou;
}; int main() {
shared_ptr<base> b = shared_ptr<base>(new drive(1.2));
shared_ptr<drive> d = dynamic_pointer_cast<drive>(b);
d->show();
}

改写成

#include <iostream>
#include <string>
#include <memory> using namespace std; class base {
public:
virtual void type() {cout << "base" << endl;}
virtual void show() {}
}; class drive : public base {
public:
drive( double d) : dou(d) {}
virtual void type() {cout << "drive" << endl;} virtual void show() {
cout << dou << endl;
} private:
double dou;
}; int main() {
shared_ptr<base> b = shared_ptr<base>(new drive(1.2));
b->show();
}
  • 使用C++新式转型,而非使用旧式转型

条款28:避免返回handles指向对象内部成分

  • 避免返回指向对象内部成员的handles(包括references,指针,迭代器)

条款29:为“异常安全”而努力是值得的

  • "异常安全函数"承诺即使发生异常也不会有资源泄漏或数据结构的破坏。

    • 基本保证:如果抛出异常,程序仍然保持有效状态
    • 强烈保证:如果抛出异常,程序状态恢复到调用前
    • 不抛异常:内置类型的操作就绝不会抛出异常

条款30:透彻了解inlining的里里外外

  • inline的申请方式

    • 隐喻方式——将函数定义于class内(包括定义域class的友元函数)
    • 声明方式——函数定义式前加关键字inline
  • inline只是个申请,编译器可以忽略
    • 大部分编译器拒绝inline太过复杂的函数(带有循环或递归的函数)
    • 所有调用virtual函数(除非是平淡无奇的)
  • 不要把构造函数和析构函数申请为inline
  • inline应该设置在小型,频繁调用的函数身上

条款31:将文件间的编译依存关系降至最低

  • 用 "声明的依赖" 替换 "定义的依赖"(让头文件尽可能自我满足,如果做不到就和其他文件的声明式相依)

    • 使用object references 或 object pointers 可以完成的任务,就不要使用objects 
    • 如果能够,尽量以class的声明式替换class的定义式
    • 为声明式提供不同的头文件
  • Handle classes
    • Handler Classes中将变量换成变量的地址(指针),头文件只给出具体的class xxx的声明,而在cpp里面才c具体lass的实现
    • 由此Handler Classes只暴露出接口,并隐藏数据结构
//Person.h
#ifndef PERSON_H
#define PERSON_H
#include <string>
#include <memory>
using namespace std;
class PersonImp;
class Person
{
public:
Person(const string& na);
string GetName() const; private:
shared_ptr<PersonImp> MemberImp;
}; #endif // PERSON_H
//Person.cpp
#include "Person.h"
class PersonImp
{
public:
PersonImp(string na) : Name(na){} string GetName() const {
return Name;
}
private:
string Name;
}; Person::Person(const string& na) : MemberImp(new PersonImp(na)) {
} string Person::GetName() const
{
return MemberImp->GetName();
}
//main.cpp
#include <iostream>
#include <string>
#include "Person.h" int main() {
Person p("xiao ming");
cout << p.GetName() << endl;
}
  • Interface classes(抽象类)

    • 利用多态,在父类抽象类中定义接口,并利用静态函数(static creat)返回具体对象
    • 抽象类暴露接口,并隐藏数据结构等
//Persion.cpp
#include "Person.h"
class RealPerson : public Person {
public:
RealPerson(const string& na) : name(na) {}
virtual string GetName() const {
return name;
} private:
string name;
}; shared_ptr<Person> Person::creat(const string &na) {
return shared_ptr<Person>(new RealPerson(na));
}
//Person.h
#ifndef PERSON_H
#define PERSON_H
#include <string>
#include <memory>
using namespace std;
class Person
{
public:
static shared_ptr<Person> creat(const string& na); virtual string GetName() const = 0;
}; #endif // PERSON_H
//main.cpp
#include <iostream>
#include <string>
#include "Person.h" int main() {
shared_ptr<Person> p = Person::creat("xiaoming");
cout << p->GetName() << endl;
}

《Effective C++》实现:条款26-条款31的更多相关文章

  1. EC读书笔记系列之14:条款26、27、28、29、30、31

    条款26 尽可能延后变量定义式的出现时间(Lazy evaluation) 记住: ★尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率 ----------------------- ...

  2. More Effective C++ 基础议题(条款1-4)总结

    More Effective C++ 基础议题(条款1-4)总结 条款1:仔细区别pointers和references 如果有一个变量,其目的是用来指向(代表)另一个对象,但是也有可能它不指向(代表 ...

  3. Effective Modern C++翻译(4)-条款3:了解decltype

    条款3 了解decltype decltype是一个有趣的东西,给它一个变量名或是一个表达式,decltype会告诉你这个变量名或是这个表达式的类型,通常,告诉你的结果和你预测的是一样的,但是偶尔的结 ...

  4. Effective Modern C++翻译(2)-条款1:明白模板类型推导

    第一章 类型推导 C++98有一套单一的类型推导的规则:用来推导函数模板,C++11轻微的修改了这些规则并且增加了两个,一个用于auto,一个用于decltype,接着C++14扩展了auto和dec ...

  5. Effective Modern C++翻译(5)-条款4:了解如何观察推导出的类型

    条款4:了解如何观察推导出的类型 那些想要知道编译器推导出的类型的人通常分为两种,第一种是实用主义者,他们的动力通常来自于软件产生的问题(例如他们还在调试解决中),他们利用编译器进行寻找,并相信这个能 ...

  6. 《Effective Modern C++》翻译--条款4:了解怎样查看推导出的类型

    条款4:了解怎样查看推导出的类型 那些想要了解编译器怎样推导出的类型的人通常分为两个阵营. 第一种阵营是实用主义者.他们的动力通常来自于编敲代码过程中(比如他们还在调试解决中),他们利用编译器进行寻找 ...

  7. 《Effective C++ 》学习笔记——条款11

    ***************************************转载请注明出处:http://blog.csdn.net/lttree************************** ...

  8. 《Effective C++》条款26 防卫潜伏的ambiguity模棱两可的状态

    每个人都有思想.有些人相信自由经济学,有些人相信来生.有些人甚至相信COBOL是一种真正的程序设计语言.C++也有一种思想:它认为潜在的二义性不是一种错误.ambiguity 这是潜在二义性的一个例子 ...

  9. Effective C++ -----条款26:尽可能延后变量定义式的出现时间

    尽可能延后变量定义式的出现.这样做可增加程序的清晰度并改善程序效率.

随机推荐

  1. 如何使用纯CSS制作特效导航条?

    先上张图,如何使用纯 CSS 制作如下效果? 在继续阅读下文之前,你可以先缓一缓.尝试思考一下上面的效果或者动手尝试一下,不借助 JS ,能否巧妙的实现上述效果. OK,继续.这个效果是我在业务开发的 ...

  2. Go开发之路(目录)

    知识点 1. Go语言 简介 2. Go语言 基本语法 3. Go语言 strings以及strconv的使用 4. Go语言 时间和日期类型 5. Go语言 指针类型 6. Go语言 流程控制 7. ...

  3. 从.Net到Java学习第十一篇——SpringBoot登录实现

    从.Net到Java学习系列目录 通过前面10篇文章的学习,相信我们对SpringBoot已经有了一些了解,那么如何来验证我们的学习成果呢?当然是通过做项目来证明啦!所以从这一篇开始我将会对之前自己做 ...

  4. 仿9GAG制作过程(二)

    有话要说: 这次准备讲述用python爬虫以及将爬来的数据存到MySQL数据库的过程,爬的是煎蛋网的无聊图. 成果: 准备: 下载了python3.7并配置好了环境变量 下载了PyCharm作为开发p ...

  5. RN开发中的报错以及告警

    报错一: Attempted to transition from state `RESPONDER_INACTIVE_PRESS_IN` to `RESPONDER_ACTIVE_LONG_PRES ...

  6. Xutils, OKhttp, Volley, Retrofit对比

    Xutils这个框架非常全面,可以进行网络请求,可以进行图片加载处理,可以数据储存,还可以对view进行注解,使用这个框架非常方便,但是缺点也是非常明显的,使用这个项目,会导致项目对这个框架依赖非常的 ...

  7. SQL Server GUID 数据迁移至MongoDB后怎样查看?

    关键字:SQL Server NEWID():BSON:MongoDB UUID 1.遇到的问题和困惑 SQL Server中的NEWID数据存储到MongoDB中会是什么样子呢?发现不能简单的通过此 ...

  8. 【记录】使用在线KMS激活Office系列

    摘要 (有能力的请支持正版office) 网上一些激活工具可能捆绑了木马.病毒.使用激活工具有风险.使用在线KMS来激活则没有这个风险. 找到你的office安装目录 已管理员身份运行cmd输入:cd ...

  9. Dijango学习_01_pycharm创建应用

    一.当初在学dijango的时候,网上的教程非常的杂且多,对于؏؏☝ᖗ乛◡乛ᖘ☝؏؏我们这种初入虎门的小白来说有太多误区 (其实是大佬的操作着实对小白不太友好,原谅我个萌新..2333..) 二.pi ...

  10. June. 22 2018, Week 25th. Friday

    Where words fail, music speaks. 言语无法表达时,音乐就会响起. From Hans Christian Andersen. Where words fail, musi ...