如何学习C++,通过对比的方式进行学习(和Python对比)
https://tangiblesoftwaresolutions.com/cplus-and-python-equivalents.html
矩阵
基本的函数定义
需要注意的是,C++
1、大括号;
2、每个类需要构造函数;
3、函数大括号后边,还需要一个分号;
类型转化
1、要用括号把 数据类型 括起来;
列表和字典的初始化
1、Python的列表是List和Dict
2、C++的有序列表是Vector(SOS,vector中的数据类型如何确定呢?vector ,用尖括号括起来);
3、C++的无序列表,或者是字典是unorder_map
,数据类型通过<>来确定,里边可以放 int,或者string;
4、每一对key和value通过大括号来维护;
5、Python是key : value;
列表和字典 Collection
C++
1、使用前,需要先include:
#include #include
2、字典的添加
C++是map.emplace(s, 1);
Python是map.update({s: 1})
emplace是安置、安放的意思;
字典的访问
C++是int i = map[s];
Python是i = map[s]
字典的长度
C++是int j = map.size();
Python是i = len(map)
字典是否为空
C++是bool b = map.empty();
Python是b = not map
字典的删除
C++是map.erase(s);
Python是map.pop(s)
erase代表擦除的意思;
注释
常量、域、局部变量
Constants, Fields, and Local Variables
未定义类型的变量(Inferred Types):
C++:auto ;
Python中的变量都是推断变量 ;
Static Field 静态域 (是不是静态变量的含义啊)
1、在Python中,静态域定义为类内,class内直接定义;
class FooClass:
staticField = 7
2、在C++中,静态变量的定义为:
class FooClass
{
static int staticField = 7;
};
实例域(instance fields) 就是说这个变量在类初始化完,或者实例化之后,才存在这个变量;
Python:在类内,通过self访问;
class FooClass:
def __init__(self):
self.instanceField = 2
C++,直接定义就好;
class FooClass
{
int instanceField = 2;
};
不能修改的变量: Local Constant
C++ :
constexpr int myConst = 2;
Python:看到全是大写的变量名,就不要再修改它了
MY_CONST = 2 #at method level - up to programmers to respect the naming convention and avoid changing it
Class Constant
构造函数和析构函数
构造函数的作用:用于新建对象的初始化工作。 析构函数的作用:用于在撤销对象前,完成一些清理工作,比如:释放内存等。
每当创建对象时,需要添加初始化代码时,则需要定义自己的构造函数;而对象撤销时,需要自己添加清理工作的代码时,则需要定义自己的析构函数。
C++ :
class Foo
{
public:
Foo() //constructor
{
}
~Foo() //destructor
{
}
};
1、要有一个~
放在析构函数前;
Python:
class Foo:
def __init__(self): #constructor
pass
def close(self): #destructor
pass
函数的默认参数
C++ :
void defaultParam(int x = 0)
{
...
}
Python :
def defaultParam(self, x = 0):
...
枚举数据类型 (根据我的工程经验,这个用的很少)
https://docs.python.org/zh-cn/3.7/library/enum.html
C++ :
enum class Simple
{
FOO,
BAR
};
1、需要注意的是,class前边还有一个enum
;
Python :
from enum import Enum
class Simple(Enum):
FOO = 0
BAR = 1
1、需要注意的是,这里要from一下,才能用Enum;
异常处理
C++ :
void ExceptionHandling()
{
try
{
}
catch (const Foo &f)
{
throw Foo();
}
catch (const Bar)
{
throw Bar();
}
catch (...)
{
throw FooBar();
}
}
Python :
def ExceptionHandling(self):
try:
pass
except Foo as f:
raise Foo()
except Bar:
raise Bar()
except:
raise FooBar()
判断 else if 和 elif
++ 和--
Increment and Decrement Operators
C++ :
++j // 先加后用
j++ // 先用后加;
Python :
j += 1
索引器Indexers
如何理解索引器
1、索引器是一种特殊的类成员,它能够让对象以类似数组的方式来存取,使程序看起来更为直观,更容易编写。
https://blog.csdn.net/lmm0513/article/details/88945865
2、它能够让对象以类似数组的方式来存取
3、对象、类、引用 的区别
1)在 Java 里都得到了简化,一切都被视为对象。因此,我们可采用一种统一的语法。尽管将一切都“看作”对象,但操纵的标识符实际是指向一个对象的“引用”(reference)。”
https://blog.csdn.net/liuhaiabc/article/details/78081129
4、所以对象,可以理解为一个实实在在的人。一个东西;
5、在对象创造出来之前,只是创建了一个引用;
6、对于C++来说:
https://blog.csdn.net/liulina603/article/details/47290963
https://blog.csdn.net/liulina603/article/details/47290963
这个博客里提到了很多概念:
类:
1、类是 C++ 的核心特性,通常被称为用户定义的类型。
2、类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。
3、类中的数据和方法称为类的成员。
4、函数在一个类中被称为类的成员。
5、https://www.runoob.com/cplusplus/cpp-classes-objects.html
6、类提供了对象的蓝图
7、
对象:
1、对象,他是利用类的构造函数在内存中分配一块内存;
2、对象是根据类来创建的。
3、类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问。
引用:
区别:
1、指针是一个变量,只不过这个变量存储的是一个地址,指向内存的一个存储单元;
2、而引用跟原来的变量实质上是同一个东西,只不过是原变量的一个别名而已。
3、理解
int a=1;int *p=&a;
int a=1;int &b=a;
上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。
而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。
指针:
好处:
1、实现多态。
2、在函数调用,传指针参数。不管你的对象或结构参数多么庞大,你用指针,传过去的就是4个字节。如果用对象,参数传递占用的资源就太大了;
3、理解
上面定义了一个整形变量和一个指针变量p,该指针变量指向a的存储单元,即p的值是a存储单元的地址。
而下面2句定义了一个整形变量a和这个整形a的引用b,事实上a和b是同一个东西,在内存占有同一个存储单元。
类的对象:
用的是内存栈,是个局部的临时变量;
类的指针:
用的是内存堆,是个永久变量,除非你释放它;
内存:
内存堆:
内存栈:
多态:
我的理解:
1、指针,就是一个变量,里边存了个在房间号;房间号对应的房间,可以是一个小房子(int、float),也可以是一个大别墅(一个对象);
2、对象用" . "操作符,引用成员;
3、指针用" -> "操作符,引用成员;
注意事项(永远也记不住的东西):
1、注意:用new ,一定要delete
2、而指针,则需利用delete 在相应的地方释放分配的内存块.
3、指针可以实现多态,直接用对象不行;
4、父类的指针可以指向子类的对象;
5、定义对象实例时,分配了内存。指针变量则未分配类对象所需内存,除非new了;
6、指针变量是间接访问,但可实现多态(通过父类指针可调用子类对象),并且没有调用构造函数。
7、直接声明可直接访问,但不能实现多态,声明即调用了构造函数(已分配了内存)。
8、当你希望明确使用这个类的时候,最好使用对象,如果你希望使用C++中的动态绑定,则最好使用指针或者引用,指针和引用用起来更灵活,容易实现多态等
9、指针可以有多级,但是引用只能是一级(int **p;合法 而 int &&a是不合法的)
10、指针的值可以为空,但是引用的值不能为NULL,并且引用在定义的时候必须初始化;
11、指针的值在初始化后可以改变,即指向其它的存储单元,而引用在进行初始化后就不会再改变了。
12、"sizeof引用"得到的是所指向的变量(对象)的大小,而"sizeof指针"得到的是指针本身的大小;
13、指针和引用的自增(++)运算意义不一样;
14、
回到主线, 什么是索引器?
https://www.cnblogs.com/hyjj/p/5387189.html
在我们开发中常见的用到索引器的地方非常之多,索引器是一个非常微妙的特殊类的成员,它能够让对象以类似数组的方式来存取,当一个类包含了数组和集合成员时,索引器将大大简化对数组或集合成员的存取操作。
索引器的本质是类
我的理解,就是类,但是这个类需要实现
get方法;
set方法;
public 数据类型 this [int index] {
get{
return str[index];
}
set{
str[index] = value;
}
}
继承 Inheritance
匿名函数 Lambdas
Python的匿名函数,我还没玩明白;
逻辑操作符 和位处理 Logical and Bitwise Operators
循环 Loops
一定要学会C++中的for each
//'for each' loop:
for (Foo f : FooList)
{
}
数学运算 Math
静态方法 Methods - Instance vs Static
命名空间:
Python用类来模拟命名空间;
操作符重载(感觉也用不上)
1、Python doesn't offer operator overloading
2、C++中使用操作符重载,目的是为了 定义一些自己很喜欢的操作。
纯虚函数 Pure Virtual Methods
纯虚函数
暂时没搞懂,有什么用:
Raw String Literals (C++) 没搞懂有什么用;
Switch用法
三元条件运算符
类型判断:Type Discovery (Python 'isinstance')
C++中没有isinstance,但是可以用dynamic_cast进行判断:
dynamic_cast<Foo*>(f)
bool b = dynamic_cast<Foo*>(f) != nullptr;
为什么加*,为什么加<>