【C++必知必会】读书笔记

本文是关于C++编程的读书笔记,详细介绍了C++的关键概念,包括数据抽象、多态、设计模式、STL、引用与指针的区别、数组形参、常量成员函数、函数对象等。通过深入理解这些概念,读者可以更好地掌握C++编程,并在面试中展现出扎实的基础知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 必知必会

为什么再一次回头看C++

自觉阅读C++相关书籍也已不少。但是有些经典内容值得不断去重复回顾。随着项目开发经验的增加以及代码能力的增强,往常看起来很经典的知识,再一次回顾会产生很多优秀的想法。这是我阅读《C++必知必会》的初衷。这本书我个人认为涵盖C++面试的所有知识,因此,各位可以通过本文来快速了解掌握这本书的干货,对于面试部分更加游刃有余。

C++正文内容

1.数据抽象
  • 类型:一组操作。
  • 抽象数据类型:一组具有某种实现的操作。
2.多态
  • 多态类型:带有虚函数的class类型。
  • 多态对象:具有不止一种类型的对象。
  • 多态基类:为满足多态对象的使用需求设计的基类。
    编写多态的原则:基类提供契约允许针对基类接口编写的多态代码对不同的特定情况起作用,同时对派生类的存在保持“健康的不知情”。
3.设计模式
  • 设计模式:一种描述面向对象设计的一种共享通用的术语方式。
4.STL
  • STL包括三大组件:容器,算法,迭代器、
    (1)容器:容纳组织元素。
    (2)算法:执行操作。
    (3)迭代器:访问容器中元素。
5.引用是别名而非指针
  • 引用与指针的区别
    (1)不存在空引用。
    (2)所有引用都要初始化。
    (3)一个引用永远指向用来对其初始化的对象。
  • 注意:一个指向常量的引用采用字面值初始化时,其引用实际被设置为指向“采用该字面值初始化”的一个临时变量。本来临时变量是在表达式末尾就被销毁的。当这类临时对象用于初始化一个常量引用时,在引用指向他们期间,临时对象会一直存在。
6.数组形参
  • 退化:C++不存在数组形参,数组传入时,实质只传入指向首元素的指针。
  • 一些标准的数组传入方式:
template<int n>
inline void average(int (&array)[n])
{
   
	average_n(array,n);
}
7.常量指针与指向常量的指针
  • const T* p1 : 指向常量T的指针。
  • T const * p2 : 指向常量T的指针。
  • T* const p3 : 常量指针,指向非常量T。
8.指向指针的指针
  • 指针数组作为形参时,会退化为指向指针的指针。
  • 函数需要改变传递给他指针的值:
    (1)将指针p移动到c的位置。
void scanTo(const char** p, char c)
{
   
	while(**p && **p!=c)
	{
   
		++*p;
	}
}

(2)C++更安全的做法是使用指针引用作为函数形参。

void scanTo(const char*& p, char c)
{
   
	while(*p && *p!=c)
	{
   
		++p;
	}
}
9.新式转型操作符
  • const_cast : 允许添加或移除表达式中类型的const或者volatile。
  • static_cast : 可跨平台移植的转型。将一个基类的指针或引用向下转型为一个派生类的指针或引用。
Shape* sp = new Circle;
Circle* cp = static_cast<Circle*>(sp);
  • reinterpret_cast : 从bit的角度看待一个对象。允许将一个东西看做完全不同的东西。
  • dynamic_cast : 用于执行从指向基类的指针安全的向下转型为指向派生类的指针。仅对于多态类型进行向下转型。(被转型的表达式的类型,必须是一个指向带有虚函数的class类型的指针)同时,执行运行期检查工作。
10.常量成员函数
  • 在类X的非常量成员函数中,this指针类型为X *const,即指向非常量X的常量指针。
  • 在类X的常量成员函数中,this的指针类型为const X* const,即指向常量X的常量指针。
  • 在类X的常量成员函数当中修改类的数据成员,标准做法是将数据成员修改成mutable,而不是const_cast。
11.编译器在类当中放的东西
  • 如果一个类声明了一个或多个虚函数,那么编译器将会为该类的每一个对象插入一个指向虚函数表的指针。
  • 虚拟继承(virtual inheritance):对象将会通过嵌入的指针,嵌入的偏移或其他非嵌入的信息来保持对其虚基类子对象(virtual base subobject)位置的跟踪。即使类没有声明虚函数,还有可能被插入了一个虚函数表指针。
    注意:不管类的数据成员的声明顺序如何,编译器都被允许重新安排他们的布局。
  • POD(plain old data):为了避免编译器重新安排他们的布局。使用struct的简单数据结构。
    注意:不要使用memcpy标准内存块复制函数来复制对象(用于复制存储区)。
  • 对象的初始化或赋值,都会涉及到对象的构造函数,构造函数时编译器建立隐藏机制的地方,该隐藏机制实现对象的虚函数等事物。向未初始化的存储区中塞入一大把比特的做法往往会达到无法预计的结果(比特冲击)。
12.赋值和初始化并不相同
  • 赋值和初始化本质上是不同的操作。
    (1)对于基础内建类型,赋值和初始化时简单的复制位。
    (2)对于用户自定义类型,初始化与赋值的区别如下(以string为例):
String::String(const char* init)
{
   
	if(!init) init = "";
	s_ = new char[strlen(init)+1];
	strcpy(s_, init);
}

String& String::operator = (const char* str)
{
   
	if(!str) str = "";
	char* tmp = strcpy(new char[strlen(str)+1], str);
	delete[] s_;
	s_ = tmp;
	return *this;
}
  • 赋值是析构后跟一个构造。
13.复制操作
  • 复制构造和复制赋值是两种完全不同的操作。两个操作总是被成对声明。
X(const X&);
X& operator=(const X&);
  • 关于实现的两种细节:
    (1)T是一个庞大而复杂的类,复制会导致不小的开销。
    (2)通过交换X各自实现的指针会极大的加快复制的过程。例如Handle的实现机制。
  • Handle class : 句柄类是这样一种类,主要由一个指向其实现的指针构成。
    注意:复制构造和复制赋值两个函数是不同的函数,但是两者应该互相兼容,产生的结果不应该有区别。
  • 标准的复制赋值实现:
Handle& Handle::operator=(const Handle& that)
{
   
	if(this!=&that)
	{
   
		//赋值
	}
	return *this;
}
14.函数指针
  • 声明一个指向特定类型函数的指针:(无需显式取得函数地址,编译器知道隐式获得函数地址,&操作符是可选的。)
void (*fp)(int);
(*fp)(12);
fp(12);

注意:非静态成员函数的地址不是一个指针,因此不可以将一个函数指针指向非静态成员函数。

  • 回调:一个可能的动作,这个动作在初始化阶段设置,以便在对将来可能发生的事件作出反应时被调用。
    注意:一个函数指针指向内联函数(inline)是合法的,但是通过函数指针调用内联函数不会导致内联函数调用,这是因为编译器无法在编译器精确地确定将会调用什么函数。
15.指向类成员的指针并非指针
  • 声明一个指向成员的指针:(使用的是classname:: *)
int C::*pimC;
  • 指向成员的指针并不指向一个具体的内存位置,而是一个类的特定成员,而不是特定对象里的特定成员。其是成员在类中的偏移量。
  • 存在从指向基类成员的指针到指向公有派生类成员的指针的隐式转换,但是不存在从指向派生类成员的指针到指向其任何一个基类成员的指针转换。
class Shape
{
   
	Point center_;
};
class Circle:public Shape
{
   
	double radius_;
};
Point Circle::*loc = & Shape::center_;
//Shape当中任何偏移量在Circle当中也是一个有效偏移量。
16.指向类成员函数的指针并非指针
  • 指向类成员函数的函数指针声明方式:
void (Shape::*mf1)(Point) = &Shape::moveTo;
  • 指向一个指向成员函数的指针,通常不能实现为一个简单的指向函数的指针。一个指向成员函数的指针的实现自身必须存储一些信息,诸如它所指向的成员函数是虚拟的还是非虚拟的,到哪里去找到恰当的虚函数表指针。
17.处理函数和数组声明
  • 对于函数的声明:
int* f1()
<think>嗯,用户问镜像源是什么意思。我需要先理解镜像源的定义,然后以简单明了的方式解释。 首先,镜像源是指一个网站或服务器,它复制了另一个源的内容,比如软件仓库、库或下载资源。主要目的是为了加快下载速度,减少延迟,尤其是在用户和原始服务器距离较远的情况下。此外,镜像源还能在主源不可用时提供备份,确保服务的稳定性。 接下来,我需要考虑用户可能的背景。用户之前询问如何下载Python软件,现在问镜像源,可能是在安装过程中遇到了下载速度慢的问题,或者看到指南里提到换源命令,所以想了解其含义。用户可能是刚开始学习编程的新手,对技术术语不太熟悉,需要通俗易懂的解释。 然后,我需要用生活中的例子来类比镜像源,帮助用户更好地理解。比如快递仓库的例子,说明镜像源如何分散存储,就近访问。这样用户能联想到实际生活中的场景,更容易理解抽象概念。 还要解释镜像源的主要作用:加速下载和提供备份。同时,需要说明为什么需要镜像源,尤其是在国内访问国外服务器时可能遇到的网络问题,比如速度慢或不稳定,这时候使用国内的镜像源就能解决这些问题。 另外,用户可能在之前的指南中看到了pip换源的命令,所以需要具体说明镜像源在Python环境中的应用,比如使用清华源、阿里云等。给出具体的命令示例,帮助用户实际应用。 还要注意结构清晰,分点说明,让用户一目了然。使用加粗或列表来突出重点,但根据系统指令,不能使用markdown格式,所以需要用文字描述结构。 最后,确保语言口语化,避免专业术语过多,用简单的中文表达,让新手也能轻松理解。同时,检查是否有遗漏的重要信息,比如镜像源的安全性问题,是否需要信任镜像源,避免下载恶意软件。 总结回答的要点:定义、作用、例子、Python中的具体应用,以及如何选择可信的镜像源。确保回答准确、全面,同时符合用户的知识水平。</think>镜像源(Mirror Source)是开发者常用的一种技术解决方案,可以理解为**数据仓库的「分身副本」**。它的核心作用可以用一个生活场景来理解: --- ### 一、快递仓库的比喻 假设你在北京网购一个广州仓库的商品: - **原始源**:广州总仓(官方服务器,距离远) - **镜像源**:北京分仓(完全复制广州仓内容,距离近) 使用镜像源就像**自动选择最近的仓库发货**,下载速度更快、稳定性更高。 --- ### 二、镜像源的核心作用 | 场景 | 使用原始源 | 使用镜像源 | |----------------------|-----------------------------------|-----------------------------------| | **下载Python安装包** | 从美国python.org下载 | 从中国清华镜像站下载 | | **安装Python库** | 连接欧洲PyPI服务器 | 连接阿里云镜像服务器 | | **更新软件** | 访问GitHub | 使用中科大镜像 | > 关键优势:**速度提升5-10倍**(实测从200KB/s → 2MB/s) --- ### 三、技术实现原理 1. **数据同步**:镜像服务器定期(如每小时)与原始源同步 ```plaintext 原始源(美国) → 网络同步 → 镜像源(中国) ``` 2. **智能路由**:当用户发起请求时,系统自动选择**物理距离最近**的服务器 --- ### 四、Python开发中的典型应用 1. **安装Python解释器**(通过镜像站下载) ```bash # 清华大学镜像地址示例 https://mirrors.tuna.tsinghua.edu.cn/python/ ``` 2. **pip安装第三方库**(换源命令) ```bash pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple ``` 3. **Anaconda环境配置**(修改.condarc文件) ```yaml channels: - defaults show_channel_urls: true default_channels: - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main ``` --- ### 五、如何选择可靠镜像源 推荐国内高校维护的镜像(安全性有保障): 1. **清华大学**:[https://mirrors.tuna.tsinghua.edu.cn/](https://mirrors.tuna.tsinghua.edu.cn/) 2. **阿里云**:[https://mirrors.aliyun.com/](https://mirrors.aliyun.com/) 3. **中科大**:[https://mirrors.ustc.edu.cn/](https://mirrors.ustc.edu.cn/) > 注意:部分企业镜像可能包含定制内容,开发环境建议优先使用高校镜像 通过使用镜像源,你能有效解决跨国网络延迟、服务器不稳定等问题,这对学习编程初期避免环境配置挫折非常重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值