[c++]c++程序设计-Y.Daniel.Liang 笔记

2024-02-02 10:48

本文主要是介绍[c++]c++程序设计-Y.Daniel.Liang 笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第九章:对象和类:
1.如果不适用public关键字,那么这些成员的可见性缺省为private。
2.自定义一个类时,应将类名中每个单词的首字母大写。
3.我们可能需要创建一个对象,却只使用一次。对于这种情况,无须为对象命名。这种对象称为匿名对象。(使用缺省构造函数)
4.包含保护。头文件中要有

#ifndef su_hpp
#define su_hpp#endif /* su_hpp */

5.如果一个函数是在类定义内实现的,那么它就自动称为一个内联函数。这叫“内联定义”。也可以在实现文件中指明函数是内联函数。

第十章:面向对象思想:
1. string str(“this is string;”);
char a[20];
strcpy(a, str.c_str());
// c_str()返回的是一个临时指针,不能对其进行操作。string转换为c字符串
char* c;
string s=”1234”;
c = s.c_str(); //c最后指向的内容是垃圾,因为s对象被析构,其内容被处理

2.把数字转换为字符串

#include <sstream>
stringstream ss;
ss << a;
string s = ss.str();

C/C++语言提供了几个标准库函数,可以将字符串转换为任意类型(整型、长整型、浮点型等)。
参数都为char*

atof():将字符串转换为双精度浮点型值。
● atoi():将字符串转换为整型值。
● atol():将字符串转换为长整型值。
● strtod():将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字。
● strtol():将字符串转换为长整值,并报告不能被转换的所有剩余数字。
strtoul():将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字。

3.分割字符串

 string s("programming is so interesting.");stringstream ss(s);string word;while (!ss.eof()) {ss >> word;cout << word << endl;}
/*ss每>>一次就
会减少一些字符。
以空格作为分界线。*/

4.静态变量由类中所有对象共享。可以通过任何对象访问,也可以通过给定作用域访问。
静态函数不能访问类的实例成员(就是非static成员:数据成员和方法)。
静态变量和静态函数都无须创建对象就可以访问。

5.在函数前面定义const表明返回的内容为const!
在函数后面定义const表明不能改变数据成员!

6.面向过程的编程要点是设计函数,而面向对象范式把数据和函数结合在一起形成对象。使用面向对象范式进行软件设计的要点是对象及对象的操作。
7. 对象合成
一个对象可以包含另一个对象,两者的关系称为合成。
合成关系实际上是聚合关系的一种特殊情况。聚合关系建模了has-a关系,描述了两个对象间的所有关系。所有者对象称为聚合对象,其类称为聚合类。主体关系称为被聚合对象,其类称为被聚合类。
一个对象可以被多个其他聚合对象所拥有。如果一个对象被一个聚合对象所有,则两个对象之间的关系就称为合成关系。
简单地说,就是一个类里有另一个类的对象作为这个类的数据成员。
8. 类设计准则
第一:内聚
一个类描述的是一个单一的实体,该类的所有操作在逻辑上是结合在一起的,并且有一个连贯的目的。例如,学生和工作人员是不同的类。
有太多职责的实体应该分开成几个类,从而把职责分开。
第二:一致
遵循标准的编程风格和命名惯例,为类、数据域和函数选择有意义的名字。
遵循一致的命名原则。相同的操作,用重载。
第三:封装
如果希望数据域被读取和修改,应该给出相应的get、set函数。如果不希望被client访问则把这些函数设为private。
第四:清晰
类应该具有清楚的约定,既易于理解又易于解释。
用户可能以任意组合、顺序及在任意环境中使用类。在设计类时,不能引入任何限制,比如假定用户在什么时候如何使用类。在设计属性时,要注意,用户可能会按任意顺序和值来设置属性,在设计函数时,也应假定函数独立于它的出现属性怒。
如果一个数据成员可以被另一个数据成员导出,则类中不应该声明这个数据成员。
第五:完整
类可被不同的用户使用,为使该类更加有用,设计的类应该提供多样化得功能。
第六:实例和静态
因为构造函数总是用来创建特定对象,所以构造函数是实例函数。在实例函数中可以调用静态变量或静态函数,但是不能再静态函数中调用实例变量或实例函数。

第11章:指针和动态内存管理
1.

random_shuffle(<#_RandomAccessIterator __first#>, <#_RandomAccessIterator __last#>);min_element(<#_ForwardIterator __first#>, <#_ForwardIterator __last#>, <#_Compare __comp#>);max_element(<#_ForwardIterator __first#>, <#_ForwardIterator __last#>, <#_Compare __comp#>);
全都返回一个指针。
放入一个数组的指针和谓词。
  1. new操作符可以在运行时为基本数据类型,数组和对象分配持久的内存空间。
    c++中,局部变量在栈中分配空间,而由new操作符分配的内存空间则出自于自由存储区或者堆的内存空间。所以局部变量是非持久的,当函数返回时,调用栈中的局部变量会被丢弃掉。
    delete只能用于指向new操作符创建的内存的指针,不能用于delete基本变量。每个new操作都应有相应的delete操作。
    如果内存无法访问也无法释放,就称为内存泄露。

  2. 调用对象的构造函数可以动态地创建对象。
    new ClassName(arguments)

  3. 使用copy constructor将创建新对象,而是用赋值操作符并不创建新对象。
    缺省的拷贝构造函数和赋值操作符进行对象复制采用一种所谓的“shallow copy”,而不是”deep copy“,即如果数据域是一个指向其他对象的指针,那么简单复制指针保存的地址值,而不是复制指向的对象的内容。
    两个指针确实会指向相同的对象获得相同的内容,但是,当两个对象的析构函数释放内存时,就有会出现把指针重复删除两次,这会产生运行时错误。
    解决方法是,在复制构造函数中再声明一个内存,复制相同的内容。

第十二章:模板、向量和栈
当设计一个通用函数时,最好先设计一个非通用函数,调式测试完毕后,再将其转换为通用版本。
c++允许为模板类的参数类型指定一个默认类型。可以作为缺省类型。但是默认类型只能用于模板类,不能用于模板函数。
如果想要动态改变一个模板类的内存大小,可以预分配一个较小的内存,当这个空间满了,就另外分配一个更大的内存用于存储前面的内容,再把前面的内存释放掉。

srand(static_cast<unsigned>(time(NULL)));                                     int a = rand()%8 + 1;随机时间。实际上是根据当前时间来选择seed。

第十三章:文件输入和输出
ifstream用于从文件中读取数据;ofstream是向文件写数据;fstream既可以读也可以写。
ofstream output(“scores.txt”);如果文件已经存在,文件的内容会被清除,系统不会给出任何警告信息。
.fail()可以检测文件是否存在。
如果希望通过一个string名字作为文件名,需要把string类转换为char*。.c_str();
流控制符可用于格式化控制台以及文件输出。

setw(int)预定给出int个空格用于输出,如果字符量不够,则在前面加空格。
getline(<#basic_istream<_CharT, _Traits> &__is#>, <#basic_string<_CharT, _Traits, _Allocator> &__str#>, <#_CharT __dlm#>);

第一个参数是文件名,第二个参数是信息输入的变量,第三个参数是间隔符。
8.

char ch = input.get();(自动进入下一个字符)
output.put(ch);

第十五章:继承和多态
关于继承:
(1)基类的私有成员不能在该基类外访问,因此派生类中不能直接使用它们,只能通过特定的函数来访问。
(2)不是所有的is-a关系都要使用继承加以建模。
(3)继承用于建模is-a关系,但不要仅仅为了重用函数,就盲目拓展一个类。
2. 当程序需要一个基类对象时,向其提供一个派生类对象是允许的。这种特性使得一个函数可适用于较大范围的对象实参,变得更加通用。我们称之为泛型程序设计。
3. 构造函数链:构造一个派生类对象时,派生类的构造函数在执行自身任务之前会先调用其基类的构造函数。
析构函数链:与构造函数相反的顺序。
4. 如果考虑一个类可能被继承,最好为它设计一个无参的构造函数,以避免编程错误。
5. 如果基类有一个自定义的拷贝构造函数和赋值操作,应该在派生类中自定义这些来保证基类中的数据能被正确拷贝。
Parent::operator=(object);
6. 在基类中定义的函数能够在派生类中被重新定义。重新定义一个函数,则必须在派生类中定义一个与基类中函数具有相同签名和返回类型的函数。(在基类中定义为虚函数)
7. 多态意味着一个超类型的变量能够引用一个子类型的对象。
将一个派生类指针赋值成一个基类指针,称为向上转型,反之称为向下转型。(可以隐式进行)
8. 如果函数不会被重定义,将其声明为非虚函数会得到更好的性能。因为在运行时动态绑定虚函数会花费更多时间和系统资源。我们把含有虚函数的类型称为多态类型。

第十六章:异常处理
异常处理能够使程序处理一些特殊现象,并继续正确地执行。

try {throw <#expression#> // 抛出一个问题。} catch (<#catch parameter#>) { // 抓住这个错误。与throw同类型。<#statements#>}

异常处理使函数的调用者可以处理该函数引发的异常。

自定义异常类最好继承标准库中的基类。
多重异常处理。一个try模块可以对应多个catch用于捕获各种不同的错误。多个不同的异常类可以派生自同一个基类。如果catch模块被设计为接受一个基类的异常对象,那它就可以接受所有派生类的异常对象了。
多个不同类型的catch顺序是很重要的。基类的catch放在子类的catch后面。
还可以使用…作为catch的参数,用于捕获所有类型的异常。可以放在最后,用于捕获所有没有被捕获的异常对象。
一个异常通过一条函数调用链不断抛出,直到被捕获或到达main函数。
如果try模块内的一条语句抛出一个异常,try模块中剩余的语句将被跳过,c++启动搜寻处理异常的代码的过程。处理异常的代码称为异常处理程序。c++会从当前函数开始,沿函数调用链你想寻找异常处理程序。找到异常处理程序的过程称为捕获异常。
如果异常处理程序无法处理一个异常,或者它想通知调用者发生了一个异常,那么c++可以把它重新抛出给函数的调用者,使得其他异常处理程序有机会处理这个异常。
你可以在函数头部声明这个函数可能抛出的异常类型。 void check(double side) throw (NonPositiveException) 如果throw()放置于函数头之后,被称为空异常说明,表明函数不能抛出任何异常。如果函数试图抛出异常,c++会调用标准函数unexpected,终止程序。
抛出一个不在异常序列中的异常,也会终止程序。但是不带异常说明的函数可以抛出任何异常,而不会引起程序终止。
异常处理机制是针对以外情况的,不要用它来处理能用if语句解决的简单逻辑错误。
使用异常处理机制可以使程序更为健壮。异常处理可以将错误处理代码和正常程序分割开来,因此是程序更易读,易维护。

常用的流控制:

#include <iomanip>setprecision()设置精度fixed;显示小数点后面的数showpoint;显示小数点setw();设置打印字段left;right;

这篇关于[c++]c++程序设计-Y.Daniel.Liang 笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/670458

相关文章

C++中使用vector存储并遍历数据的基本步骤

《C++中使用vector存储并遍历数据的基本步骤》C++标准模板库(STL)提供了多种容器类型,包括顺序容器、关联容器、无序关联容器和容器适配器,每种容器都有其特定的用途和特性,:本文主要介绍C... 目录(1)容器及简要描述‌php顺序容器‌‌关联容器‌‌无序关联容器‌(基于哈希表):‌容器适配器‌:(

C++中实现调试日志输出

《C++中实现调试日志输出》在C++编程中,调试日志对于定位问题和优化代码至关重要,本文将介绍几种常用的调试日志输出方法,并教你如何在日志中添加时间戳,希望对大家有所帮助... 目录1. 使用 #ifdef _DEBUG 宏2. 加入时间戳:精确到毫秒3.Windows 和 MFC 中的调试日志方法MFC

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规

在 VSCode 中配置 C++ 开发环境的详细教程

《在VSCode中配置C++开发环境的详细教程》本文详细介绍了如何在VisualStudioCode(VSCode)中配置C++开发环境,包括安装必要的工具、配置编译器、设置调试环境等步骤,通... 目录如何在 VSCode 中配置 C++ 开发环境:详细教程1. 什么是 VSCode?2. 安装 VSCo

C++11的函数包装器std::function使用示例

《C++11的函数包装器std::function使用示例》C++11引入的std::function是最常用的函数包装器,它可以存储任何可调用对象并提供统一的调用接口,以下是关于函数包装器的详细讲解... 目录一、std::function 的基本用法1. 基本语法二、如何使用 std::function

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

C++包装器

包装器 在 C++ 中,“包装器”通常指的是一种设计模式或编程技巧,用于封装其他代码或对象,使其更易于使用、管理或扩展。包装器的概念在编程中非常普遍,可以用于函数、类、库等多个方面。下面是几个常见的 “包装器” 类型: 1. 函数包装器 函数包装器用于封装一个或多个函数,使其接口更统一或更便于调用。例如,std::function 是一个通用的函数包装器,它可以存储任意可调用对象(函数、函数

C++11第三弹:lambda表达式 | 新的类功能 | 模板的可变参数

🌈个人主页: 南桥几晴秋 🌈C++专栏: 南桥谈C++ 🌈C语言专栏: C语言学习系列 🌈Linux学习专栏: 南桥谈Linux 🌈数据结构学习专栏: 数据结构杂谈 🌈数据库学习专栏: 南桥谈MySQL 🌈Qt学习专栏: 南桥谈Qt 🌈菜鸡代码练习: 练习随想记录 🌈git学习: 南桥谈Git 🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈🌈�

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

06 C++Lambda表达式

lambda表达式的定义 没有显式模版形参的lambda表达式 [捕获] 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 有显式模版形参的lambda表达式 [捕获] <模版形参> 模版约束 前属性 (形参列表) 说明符 异常 后属性 尾随类型 约束 {函数体} 含义 捕获:包含零个或者多个捕获符的逗号分隔列表 模板形参:用于泛型lambda提供个模板形参的名