Cherno C++ 中文学习视频第1节~第52节 错误分析
Visual Studio 中显示错误信息的方法很多,主要有 output 和 error list。其中 output 显示的错误信息非常详细,而 error list 只是捕获 output 中错误信息的一小部分。
因此,在错误分析时不要依赖 error list,它只是一个大概信息只能作为参考。
C++ 变量
不同变量类型之间的唯一区别:在 C++中的大小,即这个变量会占多少内存。
| 类型 | 占内存大小 | 输入输出格式 |
|---|---|---|
| bool | 1Byte/8bit | |
| signed char | 1Byte/8bit | %c |
| unsigned char | 1Byte/8bit | %c |
| signed short | 2Byte/16bit | %d |
| unsigned short | 2Byte/16bit | %u |
| signed int | 4Byte/32bit | %d |
| unsigned int | 4Byte/32bit | %u |
| signed long long | 8Byte/64bit | %lld |
| unsigned long long | 8Byte/64bit | %llu |
| float | 4Byte/32bit | %f |
| double | 8Byte/64bit | 输入用%lf,输出用%f |
| long double | 10Byte/80bit | 输入输出都用%Lf |
Visual Studio 最佳配置
1.在解决方案资源管理器中选择显示所有文件,新建 src 文件夹,将.cpp 文件和.h 文件移动到 src 中。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D88LXrh4-1655471238030)(/images/20220410/1.jpg " ")]
2.右键解决方案选择属性,在属性页面修改输出目录&中间目录
Debug & Release 配置属性 -> 常规 ->输出目录&中间目录 $(SolutionDIr)bin$(Platform)$(Configuration) $(SolutionDIr)binintermediates$(Platform)$(Configuration)
★C++指针
指针的实质就是一个整数(变量),一个存储内存地址的数字(变量)。
指针的类型只是告诉计算机,这个内存地址占据内存的大小。
首先,在使用 new 的时候一定要使用 delete。new 在堆栈上分配内存,需要 delete 来删除释放内存,因为这些内存不会自动释放。智能指针就是实现这一过程的一种方式。
智能指针的本质就是指针的一个包装。当你创建一个智能指针时,它会调用 new 并为你分配内存,然后基于你使用的智能指针这些内存会在某一时刻自动释放。
例如 unique_ptr 。unique_ptr 是一个作用域指针,是当超出作用域时,然后调用 delete 删除释放内存。
字符串
- 字符串实际上就是字符数组,即一组字符组成了字符串或文本。
- 空终止字符是字符串结束的地方。
- std::string::npos 是一个常熟,它等于 size_type 类型可以表示的最大值,用来表示一个不存在的位置,类型一般是 std::container_type::size_type。
4.std::string 的查找函数
find rfind find_first_of find_first_not_of find_last_of find_last_not_of
这些操作全都返回 string::size_type 类型的值。
5. 当把类(对象)传递给一个函数时,实际上是在复制这个类(对象);字符串复制十分慢。因此当传递一个字符串且是只读的情况下,确保通过常量引用传递它。
例如:
void PrintString(std::string string)
{
std::cout << string << std::endl;
}
int main()
{
std::string name = std::string("Charles") +" Hello!";
PrintString(name);
}
应改成
void PrintString(const std::string& string)
{
std::cout << string << std::endl;
}
int main()
{
std::string name = std::string("Charles") +" Hello!";
PrintString(name);
}
- 字符串字面量永远保存在内存的只读区域,记住是永远。
const 关键字
const 承若某些东西将是不变的。
- 不能修改指针指向的内容,但是指向的目标可以变
const int* a = new int; int const* a = new int;
- 不能修改指针指向的目标,但是可以修改指针指向的内容
int* const a = new int;
mutable 关键字
两种用途:一是和 const 一起使用;二是用在 lambda 表达式中。或者同时覆盖两种情况。
- 当标记类成员为 mutable 意味着类中的 const 方法可以修改这个成员。
- lambda 基本上就像一个一次性的小函数,可以写出来并赋值给一个变量。
在 lambda 中使用 mutable 意味着通过值传递的变量,可以在 lambda 中修改它。
new 关键字
new 的主要目的是在堆上分配内存。
- new 不仅分配内存,还调用构造函数。
- new 是一个操作符,这意味着可以重载这个操作符并改变它的行为。
- 通常调用 new,会调用隐藏在里面的 c 函数——malloc()函数;它代表内存分配,其实际作用传入一个 size,也就是我们需要多少字节,然后返回一个 void 指针。
- 当使用了 new 就一定要用 delete;delete 也会调用一个 free()函数,它可以释放 malloc 申请的内存。
explicit 关键字
explicit 禁用隐式(implicit)的功能。例如 explicit 关键字放在构造函数前面,这意味着没有隐式的转换。也就是说它需要显式地调用构造函数,而不是每次调用构造函数时让 C++编译器默认地进行隐式转换。
this 关键字
- 通过 this 可以访问成员函数;成员函数意思是一个属于某个类的函数或者方法。在方法内部可以引用 this,this 是一个指向当前对象实例的指针,该方法属于这个对象实例。
- 不要使用 delete this;
C++的对象生存期(栈作用域生存期)
- 栈可以被认为一种数据结构,可以在上面堆叠一些东西。假设桌子上有一堆书,需要访问中间一本,就必须把其前面的书先拿掉才能访问这本书,这就是栈在编程中的工作方式。
- 基于栈的变量,一出作用域就会被释放、销毁。
- 作用域指针基本上是一个类,是一个指针的包装器,在构造时用堆分配指针然后再析构时删除指针,所以我们可以自动化这个 new 和 delete。
C++ 复制
- 复制可以让程序按照我们想要的方式工作,但是不必要的复制会浪费性能。
- 除了引用,当编写一个变量被赋值另一个变量的代码时,都是在复制。
- 深度复制意味着我们实际上复制了整个对象。
- 某些情况复制可能更快,但是无论如何在基础使用中,使用 const 引用更好,总是通过 const 引用去传递对象
C++ 优化 (std::vector)
使用 emplace_back 代替 push_back,取消复制提高性能。
C++ 如何处理多返回值
- tuple(元组)基本上是一个类,它可以包含 x 个变量,但它不关心类型。
- pair 主要作用是将两个数据组合成一个数据,两个数据可以是同一类型或不同类型。
- pair 返回值是 2 个字符串,这是与 tuple 唯一的区别。
- 通常当需要返回多个变量时,使用 struct 结构体更加清楚。
参考
[1] 【Cherno C++】【中字】
[2] C++变量类型及内存大小
[3] std::string::npos的使用
[4] 个人博客地址



