C++选手如何快速入门Python?
1. 实际是静态语言vs动态语言 之前,一直使用C/C++做开发,最近开始尝试使用Python做一些小的工具,顺便学习一下。 包括在学生阶段,我也喜欢C/C++,有更强的控制感,程序的每一步,我都要尽可能的掌握,清楚它到底在做什么。也偶尔用过几次Java做些事情。总而言之,这都属于“静态语言”。与之相对的是“动态语言”,典型代表就是Python。 ...
1. 实际是静态语言vs动态语言 之前,一直使用C/C++做开发,最近开始尝试使用Python做一些小的工具,顺便学习一下。 包括在学生阶段,我也喜欢C/C++,有更强的控制感,程序的每一步,我都要尽可能的掌握,清楚它到底在做什么。也偶尔用过几次Java做些事情。总而言之,这都属于“静态语言”。与之相对的是“动态语言”,典型代表就是Python。 ...
0. C++ 中的锁 两种最常用的:互斥锁、条件锁,此外还有自旋锁 1. C++ 中的条件变量 2. 生产者消费者模型 引出虚假唤醒的问题 3. 虚假唤醒 有多个线程在wait同一个条件变量时,当条件变量发出notify_one的时候,各个线程去竞争锁,此时,只能有一个线程得到锁,但是,其他线程在收到notify_one信号时,线程已经从wait队列换到锁竞争的队列了(不再等待notify的通知了,而是等待其他线程解除对锁的占用),一旦某个线程拿到锁了,就会立刻向下执行代码,但此时,条件可能已经变了,不是预期的条件了。 ...
1. 编译器默认添加的函数 自写类的时候,如果没有显式的写出来构造函数、析构函数、拷贝构造函数、拷贝赋值函数。如果程序中这些函数被需要(被调用),编译器就会默认的创建这些函数。 默认的构造函数和析构函数都是空实现的。 默认的拷贝构造函数和拷贝赋值函数都是浅拷贝。 如果有自己写的一个或者多个构造函数(不管有无参数),那么编译器都不会再添加默认的构造函数。 ...
0. placement new 即 原地构造。 用法: int *p = new int(10); // new operator new(p) int(1000); // 在 p 指向的内存上 构造一个int对象,即placement new // 此时 *P 为 1000。 因为是在一个已有的空间上构造对象,所以,空间的释放,就由free或者delete负责了。 0.1 重载placement new 与后边的 3 :operator new的重载无异,就是可以多增加几个函数,但是,第一个参数必须是std::size_t 类型,这个参数接收的是 new 后边类型的大小,不用显式传参,默认会传递。 重载示例: ...
0. 必要性 C语言中的类型转换,没有安全检查,安全性需要程序猿来保证,C++提供了4种类型转换的方法,在一定程度上保证转换的安全性。 重点是 dynamic_cast 1. const_cast 仅用于去除类型的const属性,也是四种类型转换中,唯一可以去掉const限制的方法。 只能转换 指针、引用、this(在类内的时候用)。 2. static_cast 隐式转换能转的,它都能转,但是也有例外(父类指针 转 子类指针)。 ...
1. 什么是智能指针 简而言之,为了更安全的使用指针。 实现方式简单来说,就是用一个模板类把一般的指针包装起来。用这个类来维护内部指针的释放操作。 std中有四种智能指针。 auto_ptr(已弃用) unique_ptr shared_ptr weak_ptr 2. auto_ptr 比较简单的智能指针,实现逻辑如下代码。 实现的原则是:内存空间只能由一个指针所拥有。 存在的问题:拷贝和赋值后,原对象内部的指针会为空,有风险。 ...
0. 为什么要内存对齐? 经过内存对齐之后,一个最最主要的原因是可以使得CPU的内存访问速度大大提升。 内存空间按照byte划分,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 ...
转自:https://www.cnblogs.com/stemon/p/4406824.html 前几天女票问了我一个阿里的面试题,是有关C++语言的const常量的,其实她一提出来我就知道考察的点了:肯定是const常量的内存不是分配在read-only的存储区的,const常量的内存分配区是很普通的栈或者全局区域。也就是说const常量只是编译器在编译的时候做检查,根本不存在什么read-only的区域。 ...
0. 模板 C++中除了有面向对象的思想,还有泛型编程的思想,泛型编程利用的主要技术就是模板。 C++中两种模板:函数模板、类模板 语法: template<typename T> 函数声明或定义 含义: template 固定的,声明创建模板 typename 表明后边的T是一种数据类型,也可以用class代替 T 类似形参,任意的合法字符都可以,习惯上用 T 模板有两种类型推导的方式,一种是编译器自动推导,另外一种是程序猿手动指定: ...
0. 基本语法 多态是面向对象的三大特性之一。 多态:多态即调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。 多态分为两类 静态多态:函数重载 和 运算符重载 属于静态多态,是对函数名的复用。 动态多态:派生类和虚函数实现运行时多态。 静态多态的函数地址早绑定, 编译阶段确定函数地址。 动态多态的函数地址晚绑定, 运行阶段确定函数地址。 引入虚函数,就是为了通过函数重写实现多态的效果。 ...
0. 基本语法 继承是面向对象的三大特性之一。 class 子类 : 继承方式 父类 从父类继承来的表现其共性,而新增的成员表现其个性。 1. 继承方式 三种继承方式 public protected private 父类中的private成员,无论哪种方式都不能访问。 2. 继承中的对象模型 问题:从父类继承来的成员,哪些属于子类对象中? 输出子类的sizeof可以看出,父类中的所有非静态成员都会被子类继承下去,无论哪种继承方式。 ...
0. 类的4个默认函数 4个函数:构造函数、析构函数、拷贝构造函数、赋值号重载函数。 在定义类时,如果没有自定义这些函数,编译器会提供默认的函数,在默认的函数中,构造函数、析构函数默认空实现,拷贝构造函数、赋值号重载函数默认是浅拷贝。 拷贝构造函数作用: 参数是一个同类型的对象,直接拷贝这个参数的所有属性,注意,这个拷贝默认是浅拷贝,需要深拷贝的话需要重载拷贝构造函数。 【注】 ...
0. 引用的本质 本质:引用在C++内部的实现是一个指针常量(* const)。 const就限制了必须要初始化,并且初始化以后不可更改。 它不是一个对象,所以没有引用的引用。 1. 注意事项 引用必须初始化 引用在初始化后不可修改 2. 引用做函数参数 与指针传递相似 3. 引用做函数返回值 与指针一样,不要返回局部变量(栈区空间)的引用 函数的调用可以作为左值 int& test(){ static int a = 10; return a; } int main(){ int &ss = test(); test() = 100; // 引用作为左值 cout << ss << endl; // 输出100 return 0; } 4. 常量引用 作用:在函数中用来修饰形参,防止误操作。 ...
两个比较容易混淆的概念。 0. 记忆方法 const int * p; int * const p; int const * p; 这是常见的三种写法,按照从左至右的顺序记忆,按照从右至左的顺序理解。 记忆 只关注const 和 * 的先后先后顺序,const读做常量,*读做指针。 参考《Effective c++》Item21上的做法,如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。 ...
Lambda表达式 Lambda表达式 形式 [capture](params) -> return-type{ function body } 说明 capture 需要捕获的外部变量列表(这里的外部变量不包括程序的全局变量,指的是匿名函数父作用域内的变量)。 如果这个匿名函数需要调用本匿名函数以外的变量,那么就需要在这个[ ] 中进行捕获,捕获包括捕获的变量名称和捕获的方式(值和引用)。 例如: [ ] 表示不捕获外部的任何变量 [=] 表示捕获外部的所有变量(父作用域内),是以值的方式捕获(不可修改)。 [&] 表示捕获外部的所有变量(父作用域内),是以引用的方式捕获(可修改)。 [=, &x, &y] 表示捕获外部的所有变量(父作用域内),其中x和y以引用的方式捕获,其他变量以值的方式捕获。 [&, x, y] 表示捕获外部的所有变量(父作用域内),其中x和y以值的方式捕获,其他变量以引用的方式捕获。 capture注意事项 如果不进行变量捕获,那么在匿名函数内,不可以使用外部变量。 捕获列表内,不允许重复捕获。比如 [=, a],=已经说明所有的变量(包括a)以值的方式捕获,后边的a又进行了一次说明,这是不允许的。 捕获任何非父作用域内变量或者程序的全局变量,都会出错。 [this]只能以值的方式捕获 ...