kongen kongen
首页
导航站
  • 学习教程

    • Opencv教程
    • C++基础教程
    • C++_Primer教程
    • CUDA编程
  • Opencv
  • CNN
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 面试题库

    • HTML
    • CSS
    • jQuery
    • Vue
    • 零碎
  • 面试心得

    • 杂言碎语
  • 十架道路

    • 十架七言系列
    • 基督徒生活观
    • 上帝的蓝图
  • 摘抄收录

    • ☆ 励志鸡汤
    • ❀ 人间烟火
  • 读书笔记

    • 《小狗钱钱》
    • 《穷爸爸富爸爸》
    • 《聪明人使用方格笔记本》
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

Kongen

你好呀(✪ω✪)
首页
导航站
  • 学习教程

    • Opencv教程
    • C++基础教程
    • C++_Primer教程
    • CUDA编程
  • Opencv
  • CNN
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 面试题库

    • HTML
    • CSS
    • jQuery
    • Vue
    • 零碎
  • 面试心得

    • 杂言碎语
  • 十架道路

    • 十架七言系列
    • 基督徒生活观
    • 上帝的蓝图
  • 摘抄收录

    • ☆ 励志鸡汤
    • ❀ 人间烟火
  • 读书笔记

    • 《小狗钱钱》
    • 《穷爸爸富爸爸》
    • 《聪明人使用方格笔记本》
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
关于
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 第一章 开始
  • 第二章 变量和基本类型
  • 第三章 字符串、向量和数组
  • 第四章 表达式
  • 第五章 语句
  • 第六章 函数
  • 第七章 类 (Class)
  • 第八章 IO库
  • 第九章 顺序容器
  • 第十章 泛型算法
  • 第十二章 动态内存
  • 第十三章 拷贝控制
  • 第十四章 重载运算与类型转换
  • 第十五章 面向对象程序设计
  • 第十六章 模板和泛型编程
  • 第十七章 标准库特殊设施
  • 第十八章 用于大型程序的工具
    • 异常处理
      • 抛出异常
      • 捕获异常
      • 构造函数
      • noexcept异常说明
      • 异常类层次
    • 命名空间
      • 命名空间定义
      • 使用命名空间成员
      • 类、命名空间与作用域
      • 重载与命名空间
    • 多重继承与虚继承
      • 多重继承
      • 类型转换与多个基类
      • 多重继承下的类作用域
      • 虚继承
      • 构造函数与虚继承
  • 第十九章 特殊工具与技术
  • README
  • C++_Primer教程
kongen
2024-09-12
目录

第十八章 用于大型程序的工具

# 第十八章 用于大型程序的工具

大规模应用程序的特殊要求包括:

  • 在独立开发的子系统之间协同处理错误的能力。
  • 使用各种库进行协同开发的能力。
  • 对比较复杂的应用概念建模的能力。

# 异常处理

异常处理(exception handling)机制允许程序中独立开发的部分能够在运行时就出现的问题进行通信并作出相应的处理。

# 抛出异常

在C++语言中,我们通过抛出(throwing)一条表达式来引发(raised)一个异常。异常类型和当前的调用链决定了哪段处理代码(handler)将用来处理该异常。

程序的控制权从throw转移到catch模块。

栈展开:当throw出现在一个try语句块时,检查该try语句块相关的catch字句,若有匹配则处理;若无匹配,则继续检查外层的try匹配的catch。

若一个异常没有被捕获,则它将终止当前的程序。

对象销毁:

  • 块退出后,它的局部对象将被销毁。
  • 若异常发生在构造函数中,即使某个对象只构造了一部分,也要确保已构造的成员正确地被销毁。
  • 将资源释放放在类的析构函数中,以保证资源能被正确释放。析构函数本身不会引发异常。

# 捕获异常

若无需访问抛出的异常对象,则可以忽略捕获形参的名字。

通常,若catch接受的异常与某个继承体系有关,则最好将该catch的参数定义成引用类型。

搜索catch未必是最佳匹配,而是第一个匹配,因此,越细化的catch越应该放在catch列表前段。

重新抛出:catch代码执行一条throw;将异常传递给另一个catch语句。

捕获所有异常:catch(...)

# 构造函数

处理构造函数初始值异常的唯一方法是将构造函数协程函数try语句块。

示例:

template <typename T>
Blob<T>::Blob(std::initializer_list<T> il) try: 
    data(std::make_shared<std::vector<T> >(il){
        /*函数体*/
    } catch(const std::bad_alloc &e){ handle_out_of_memory(e); }
1
2
3
4
5

# noexcept异常说明

使用noexcept说明指定某个函数不会抛出异常。

示例:

void recoup(int) noexcept; //C++11
coid recoup(int) throw(); //老版本
1
2

# 异常类层次

标准exception层次:

  • exception
    • bad_cast
    • bad_alloc
    • runtime_error
      • overflow_error
      • underflow_error
      • range_error
    • logic_error
      • domain_error
      • invalid_argument
      • out_of_range
      • length_error

自定义异常类:

示例:

class out_of_stock: public std::runtime_error {
    explicit out_of_stock(const std::string &s):
    std::runtime_error(s){ }
};
1
2
3
4

# 命名空间

多个库将名字放置在全局命名空间中将引发命名空间污染(namespace pollution)。命名空间(namespace)分割了全局命名空间,其中每个命名空间是一个作用域。

# 命名空间定义

命名空间的定义包含两部分:1.关键字namespace;2.命名空间名称。后面是一系列由花括号括起来的声明和定义。命名空间作用域后面无需分号。

示例:

namespace cplusplus_primer{
    
}
1
2
3

每个命名空间都是一个作用域。定义在某个命名空间内的名字可以被该命名空间内的其他成员直接访问,也可以被这些成员内嵌套作用域中的任何单位访问。位于该命名空间之外的代码必须明确指出所用的名字是属于哪个命名空间的。

命名空间可以是不连续的。这点不同于其他作用域,意味着同一命名空间可以在多处出现。

内联命名空间(C++11):

无需使用该命名空间的前缀,通过外层命名空间就可以直接访问。

示例:

namespace cplusplus_primer{
    inline namespace FifthEd{
        // 表示本书第5版代码
        class Query_base {};
    }
}

cplusplus_primer::Query_base qb;
1
2
3
4
5
6
7
8

未命名的命名空间:

指关键字namespace后面紧跟花括号的用法。未命名的命名空间中定义的变量拥有静态的声明周期:在第一次使用前创建,直到程序结束才销毁。不能跨越多个文件。

# 使用命名空间成员

像namespace_name::member_name这样使用命名空间的成员非常繁琐。

命名空间的别名:

namespace primer = cplusplus_primer;
1

using声明(using declaration):

一条using声明语句一次只引入命名空间的一个成员。

using std::string;

string s = "hello";
1
2
3

using指示(using directive):

使得某个特定的命名空间中所有的名字都可见。

using namespace std;

string s = "hello";
1
2
3

# 类、命名空间与作用域

namespace A{
    class C1{
        public:
            int f3();
    }
}

A::C1::f3
1
2
3
4
5
6
7
8

# 重载与命名空间

using声明语句声明的是一个名字,而非特定的函数,也就是包括该函数的所有版本,都被引入到当前作用域中。

# 多重继承与虚继承

# 多重继承

# 类型转换与多个基类

# 多重继承下的类作用域

  • 当一个类拥有多个基类时,有可能出现派生类从两个或更多基类中继承了同名成员的情况。此时,不加前缀限定符直接使用该名字将引发二义性。

# 虚继承

  • 虚继承的目的是令某个类做出声明,承诺愿意共享它的基类。其中,共享的基类子对象成为虚基类。在这种机制下,不论虚基类在继承体系中出现了多少次,在派生类中都只包含唯一一个共享的虚基类子对象。
  • 虚派生只影响从指定了虚基类的派生类中进一步派生出的类,它不会影响派生类本身。

# 构造函数与虚继承

  • h含有虚基类的对象的构造顺序与一般的顺序稍有区别:首先使用提供给最底层派生类构造函数的初始值初始化该对象的虚基类子部分,接下来按照直接基类在派生列表中出现的次序对其进行初始化。
  • 虚基类总是先于非虚基类构造,与它们在继承体系中的次序和位置无关。
编辑 (opens new window)
第十七章 标准库特殊设施
第十九章 特殊工具与技术

← 第十七章 标准库特殊设施 第十九章 特殊工具与技术→

最近更新
01
附录L_CUDA底层驱动API
02-08
02
附录K_CUDA计算能力
02-08
03
附录J纹理获取
02-08
更多文章>
Theme by Vdoing | Copyright © 2024-2025 Kongen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×