《C++高级编程》-软件工程

第二十四章 充分利用软件工程方法

24.2 软件生命周期模型

瀑布模型:规划-设计-实现-单元测试-子系统测试-整合测试-评估。上一步完成才开始下一步
生鱼片模型:以上步骤前后有重叠部分

螺旋类模型-风险驱动的开发过程,基本思想:出错也没关系,下一轮会修复这个问题。
发现阶段:构建需求,确定目标,替代方案,其他约束
评估阶段,考虑评估方案,分析风险,构建原型系统。朱忠此阶段的风险评估和解决。
开发阶段,期间任务由前两个阶段确定的风险决定。
分析阶段:信息工程下一个周期计划。

规划(主需求)-原型(可展示)- 构建实现高风险组件。三个步骤重复上述四个阶段
相当于允许迭代的瀑布模型

迭代时间范围太长成了瀑布模型。

敏捷开发注重客户需求的快速实现,而不是开发过程本身的高效。

24.3 软件工程方法论

24.3.1 UP

unified process——统一过程
迭代和增量的软件开发过程。根据项目的特定需求进行定址。分四个阶段:
起始阶段(inception)通常短暂。包括可行性研究,编写业务案例,决定内部开发还是外包,确定成本和时间线。
细化阶段(elaboration)把大多数需求记录,消除风险,验证系统架构。为验证架构,实现核心功能以验证它可以支撑整个系统
构建阶段(construction)在架构上完成全部需求
交付阶段(transition)交付并更具客户反馈,后续处理

P582 图24-6

24.3.2 RUP

rational unified process。rational统一过程。

24.3.3 Scrum

实现敏捷模型。定义了日常使用的方法。
是迭代过程,管理软件开发项目的手段。
每个迭代称为sprint周期,是scrum过程的核心部分。
sprint周期的长度在项目开始决定–通常2~4周。每个周期结束时,目标是有一个完全可用且经过测试的软件版本。它要是客户需求的一个子集。
因为需求易变,可以将每个周期的结果发给客户,反馈意见。

有三个角色
Product Owner,客户与其他人之间桥梁作用–根据客户描述编写产品要实现的具体功能。
Scrum Master,负责保持过程运行,可以是团队的一部分,但不是团队领导,scrum中团队自我管理。sm是团队的联络人,使成员专注于自己的任务,保证遵循scrum过程,组织日常scrum会议。
团队本身,负责开发,精简,不多于10人。

过程;
强制没人例会-daily scrum/standup。简短,回答三个问题:
自从上次daily scrum会议以来做了什么
本次会议后打算做什么
为达到目标面临什么问题,SM关注该部分,并尝试会议之后解决。
每个周期前有个计划会,讨论新周期内从需求总表上去除那部分功能来实现,分解成小任务,评估工作量,期间需求总表别乱改。
同时分todo,in progress,done,每个任务分类
之后review分析总结该周期内问题,同时给出可展示demo

P583

24.3.4 极限编程

Extreme Porgramming-XP
精细的反馈–提供与编码,规划和测试相关的4条指导原则。
结对编程:二人编写,一个写,一个审查
计划策略:版本计划与开发人员和客户相关,旨在确定未来的版本需求包括哪些要求;迭代计划仅与开发人员相关,规划开发人员的实际任务。功能被分解成不超过五天的任务。
不断测试:不断对负责的部分代码编写单元测试,它通常是一小块代码。可以在实现功能之前编写,如果测试时完成的,就应该知道什么时候代码才算完成,因为此时才能通过测试----TDD(test driven development,测试驱动开发)

持续的过程
倡导持续集成子系统,从而及时发现子系统之间的不匹配,必要时重构代码。
不断整合:频繁地整合代码进项目,通过测试暴露问题
必要时重构:重设计
构建小型发布:不要一次实现太多。最重要的功能才会进入发布版本,迫使确定哪些工程真正重要

寻求共识
为了共享代码
共同的编码标准:命名约定和缩进约定。如果有很强的个人风格,那么需要更好地定义编码标准。
共享代码:允许修改完成其他人负责的代码,每个人都熟悉其他人负责的部分。
简化设计:设计简单,能用的对象存储,满足当前需求,而不是包罗万象,最终成了STL。立足当下,修改是明天的事情。
有共同的隐喻(metaphor):对系统有高层次的看法。统一的词汇。

24.3.5 软件分流

software triage:快要GG的项目,啥都却的情况下,利用剩下的资源完成任务。保留核心,去掉非必要功能

第二十五章 编写高效的C++程序

第二十六章 测试

第二十七章 调试

错误日志工具 win上的实践报告API
boost.log
log4cpp

27.4.3 断言–运行时

<cassert>头文件定义了assert宏,接收一个布尔表达式,如果为false则打印一条错误信息并终止程序。—发生于灾难性错误

27.4.4 崩溃转储–更有价值

内存转储,是一个转储文件,崩溃时创建,包含:哪个线程在运行,所有线程的调用堆栈等。与平台相关的文档,或第三方库breakpad
建立符号服务器和源代码服务器。符号服务器用于存储软件发布二进制版本的调试符号,可以用于解释来自客户的崩溃转出。
源代码服务器储存代码的所有修订。

27.5 静态断言

static_assert编译时对断言求值。接收两个参:编译时求值的表达式和字符串。为false时将给出包含指定字符串的错误提示。
核实是否是64位编译器编译

static_assert(sizeof(void*) == 8, "Requires 64-bit compiliation");

32位则指针是4个字符,报错:
test.cpp(3): error C2338: Requires 64-bit compilation
C++17 ,字符串参数可选。此时出错,错误信息和编译器相关了。

结合trait
static_assert(is_base_of_v<Base1, T>);

当不同参数类型的base2调用base1的方法时,就会报错

第二十八章 使用设计技术和框架

28.1 容易忘记的语法

RAII

28.2.2 双分派

实际上是多分派的特例。多分派是根据两个或多个对象的运行时类型选择行为。在实践中,双分派可根据两个对象的运行时类型选择行为。
例如:
animal基类派生出其他类,都包含eat()和eatenby()方法,这样当调用eat()方法时,多态性确定调用哪一个动物类的eat()方法。调用eatenby()时,多态性再次确定要调用哪个类的方法版本,此时调用prey对象运行时类型的eatenby()

bool Bear::eat(const Animal& prey) cosnt
{
	return prey.eatenby(*this);
}

*this的运行时类型始终与编译时类型相同,这样编译器可为实参(这里是Bear)调用eatenby()的正确重载版本。

#include <iostream>

using namespace std;

// Forward declarations.
class Fish;
class Bear;
class TRex;

class Animal
{
public:
	virtual bool eats(const Animal& prey) const = 0;

	virtual bool eatenBy(const Bear&) const = 0;
	virtual bool eatenBy(const Fish&) const = 0;
	virtual bool eatenBy(const TRex&) const = 0;
};

class Bear : public Animal
{
public:
	bool eats(const Animal& prey) const override { return prey.eatenBy(*this); }

	bool eatenBy(const Bear&) const override { return false; }
	bool eatenBy(const Fish&) const override { return false; }
	bool eatenBy(const TRex&) const override { return true; }
};

class Fish : public Animal
{
public:
	bool eats(const Animal& prey) const override { return prey.eatenBy(*this); }

	bool eatenBy(const Bear&) const override { return true; }
	bool eatenBy(const Fish&) const override { return true; }
	bool eatenBy(const TRex&) const override { return true; }
};

class TRex : public Animal
{
public:
	bool eats(const Animal& prey) const override { return prey.eatenBy(*this); }

	bool eatenBy(const Bear&) const override { return false; }
	bool eatenBy(const Fish&) const override { return false; }
	bool eatenBy(const TRex&) const override { return true; }
};


int main()
{
	Fish myFish;
	Bear myBear;
	TRex myDino;
	
	cout << boolalpha
	cout << "Fish eats bear? " << myFish.eats(myBear) << endl;
	cout << "Fish eats dino? " << myFish.eats(myDino) << endl;
	cout << "Dino eats bear? " << myDino.eats(myBear) << endl;
	cout << "Bear eats fish? " << myBear.eats(myFish) << endl;
}

28.2.3 混入类

如果类在一条轴上组织成层次结构,但他们还与另一条轴有相似之处,混入类将特别有用。此时可在一个类结构中,按照需要加入另一条轴的划分的依据,写成类。之后按照需要从该混入类继承。P661

28.3.1 使用框架

开始使用新框架时,首先要确定框架的工作原理,遵循什么设计原理,开发人员传达的理念是什么,框架广泛使用语言的那些功能。

28.3.2 MVC范型

框架采用的方法与面向对象的设计方法存在差异,常见的是model-view-controller(模型-视图-控制器),来源是:许多应用程序经常处理数据集合,有一个或多个数据视图,还会操纵数据。
MVC中,数据集合成为模型,实践中采用类的形式,包含多个获取器和设置器。
视图是模型的特定可视化形式,两个视图在同一数据上操作,以不同形式查看相同信息。优点:将数据和显示分开后,可以更好组织代码,方便创建其他视图。
控制器是一段代码,通过更改模型来响应一些事件。也可操纵视图。

第二十九章 应用设计模式-待补充

第三十章 开发跨平台和跨语言应用程序

30.1 跨平台开发

30.1.1 架构问题

1.整数大小。<cstdint> 中规定了一些整数类型实际大小
2.二进制兼容性。cpu的指令不同。不同平台需重新编译
3.地址大小。整数大小和指针大小未必一样。
3.字节顺序。大小端。

30.1.2 实现问题

不同编译器对C++标准解释不同。
不同的库对C++实现也不同

30.1.3 平台专用功能

1.图形界面 Qt wxWidgets
2.联网 抽象的套接字socket
3.OS事件和引用程序交互 C++很少与操作系统交互,不直接支持诸如复制和粘贴的操作,可以用库实现,如图形库
4.低级文件 通过系统API实现文件操作
4.线程 C++17已有,或者第三方

30.2跨语言开发–待补充

C和C++
C支持变长数组,C++不支持

//extern关键字告知编译器,链接的代码时C++编译
extern "C++" {
	void fun(int i);
}
//更常见的是头文件级别,将头文件打包到extern块中,以
//指定定义函数的整个头文件是C编写的
extern "C"{
	#include "graphicslib.h"
}

//另一个常见模型是编写单个头文件,然后根据条件针对C或C++编译
#ifdef __cplusplus
	extern "C" {
#endif
	fun1();
#ifdef __cplusplus
	} //matches extern "C"
#endif

C#调用C++代码
以下代码将编译为dll库,接收Unicode字符串,返回一个整数

import <iostream>;
using namespace std;
extern "C"
{	//vs处理方式,输出dll
	__declspec(dllexport) int functionInDLL(const wchar_t* p)
	{
		wcout << L"The following string was received by C++:\n    '";
		wcout << p << L"'" << endl;
		return 42;    // Return some value...
	}
}

using System;
using System.Runtime.InteropServices;

namespace HelloCSharp
{
    class Program
    {	//此处动态引入dll,告知C#从何处查找函数实现,编码为Unicode
        [DllImport("HelloCpp.dll", CharSet = CharSet.Unicode)]
        //指定函数的实际圆形。
        public static extern int functionInDLL(String s);

        static void Main(string[] args)
        {
            Console.WriteLine("Written by C#.");
            int result = functionInDLL("Some string from C#.");
            Console.WriteLine("C++ returned the value " + result);
        }
    }
}

附录A C++面试

附录D UML简介

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 《C高级编程(第2版)》是一本关于C语言高级编程技术的书籍。C语言作为一门广泛应用于嵌入式系统和系统级编程编程语言,具有高性能和强大的功能。本书主要面向已经掌握C语言基础知识的读者,帮助他们进一步深入学习C语言高级编程技术。 本书的主要内容包括C语言高级数据类型和数据结构、指针的应用、内存管理、多线程编程、文件IO、网络编程等方面。通过系统地讲解这些高级编程技术,读者能够提升对C语言的理解和应用能力,能够更好地解决复杂的编程问题。 此外,本书还通过大量的实例和案例,帮助读者掌握各种高级编程技巧。通过实践,读者可以更好地理解和应用所学的知识,提高编程水平。同时,本书还提供了大量的习题和实验,读者可以通过完成习题和实验来巩固所学的知识。 总的来说,《C高级编程(第2版)》是一本很好的C语言高级编程入门书籍,适合已经具备一定C语言基础的读者学习和参考。无论是想深入学习C语言的技术人员,还是嵌入式系统和系统级编程开发者,都能够从本书中受益。 ### 回答2: 《C高级编程(第2版)》是一本经典的编程书籍,主要讲解C语言高级知识和技巧。本书的作者是Peter Van der Linden,他是一位经验丰富的软件工程师和作家。 这本书主要分为11个章节,内容包括C语言高级特性、内存管理、指针、位操作、函数、数组和字符串、结构体和联合体、文件操作、预处理器和C语言高级技巧。每个章节都有详细的讲解和示例代码,非常适合有一定C语言基础的读者。 本书的一个重点是教授读者如何编写高效、可靠和可维护的C代码。它介绍了一些常见的编程技巧,例如内存管理、指针的正确使用、位操作和优化等。这些技巧可以帮助读者写出更高效、更可靠的程序,并且可以加深对C语言的理解。 此外,本书还介绍了一些高级主题,如函数指针和函数式编程、结构体和联合体的使用、文件操作和预处理器的技巧。通过对这些高级特性的学习,读者可以进一步提升自己的编程水平,并且能够更好地应对复杂的编程问题。 总体来说,《C高级编程(第2版)》是一本非常有价值的C语言编程书籍。它不仅可以帮助读者巩固和拓展C语言的基础知识,还能教会读者一些高级编程技巧。无论是初学者还是有一定经验的程序员,都可以从这本书中受益匪浅。 ### 回答3: 《C语言高级编程(第2版)》是一本关于C语言编程技术的书籍,它是一本经典的教材,适合那些已经具备一定C语言基础的读者。 在这本书中,作者深入讲解了C语言高级技术和特性。首先,它详细介绍了C语言的结构和语法,使读者对C语言有全面深入的了解。然后,它探讨了C语言中的一些高级编程概念,如指针、内存管理和动态内存分配等。这对于那些希望在C语言中编写高效和优化的程序的读者非常有帮助。 此外,这本书还涵盖了一些C语言中常用的编程技巧和技术,如文件操作、多线程编程和网络编程等。这些内容使得读者可以更加灵活和高效地应用C语言进行各种编程任务。 同时,《C语言高级编程(第2版)》还包括了大量的实例和案例,通过这些实例,读者可以学习到如何解决实际问题和应用C语言进行开发。这些案例涵盖了多个领域,如图形化界面、嵌入式系统和科学计算等,使得读者可以在不同的领域中灵活运用所学的知识。 总之,《C语言高级编程(第2版)》是一本非常适合有一定C语言基础的读者学习的书籍。通过学习这本书,读者可以更加深入地了解C语言高级特性和技术,并且能够应用这些知识进行实际开发编程。无论是对于学生还是职场人士,这本书都是一个很好的参考书,能够提升读者的编程水平和技能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值