
面向对象程序设计
week 1
C++的介绍
the first c++ programme
1 |
|
read input
1 |
|
Using Objects
The string class
1 |
|
string class 的应用
1 |
|
File I/O
1 |
|
I/O example
1 |
|
regex example(替换字符)
1 |
|
week 2
A Quick Tour of C++
- 这一节课cx老师通过介绍排序算法引出c++中的模板、自定义类、类的继承,快速介绍了c++中的几个性质(cx老师也说如果这一节课的每个步骤完全弄懂,这门课不用来听了
bushi) - 首先用c++写了选择排序的程序,和C语言大差不差
- 以下的例子介绍了C++中的在函数定义中显式声明模板参数。这样我们对于不同的变量类型都可以适用。
1 |
|
设计结构体来排序
- 引用传递(&):直接访问原始对象,这样能方便我们不额外开辟一个空间,直接修改原始对象。(当然对于常量变量并不会修改原始对象)
- 值传递:会额外开辟一个原始对象的副本。
- 对于我们的选择排序对于我们自定义的变量,我们需要自己定义我们的比较规则与输出规则。
1
2
3
4
5
6
7
8
9
10
11struct student{
int id;
std::string name;
};
bool operator<(const student &s1,const student &s2){
return s1.id<s2.id;
}
std::ostream &operator<<(std::ostream&out,const student& s)
{
return out << "("<<s.id<<","<<s.name<<")";
}引入自定义类,class(其中类里面的字段为private),而前面的结构体其实本质上的字段是public,所以我们在main函数中对class进行初始化程序会报错。这就涉及到我们在自定义类构造函数。
1 |
|
- 我们思考是否有一个抽象类,类似于前面的抽象类型来管理多个性质与成员相同的类。这就涉及c++的继承
- 注意抽象类的定义,抽象类定义为纯虚函数,即没有函数体,只有函数声明,其子类必须实现该函数。子类实现的函数的值存在在抽象类的protected域中。
- 继承的语法为:class 子类:访问修饰符 父类{};
- 子类实现父类的纯虚函数时,子类必须使用override关键字来修饰。
- 此时在main函数中我们通常涉及指针数组来方便操作对象
1 |
|
- 我们又仿照前面的结构体,按照下面的代码想要输出我们刚刚得到的结果,但是发现无法访问area和perimeter。因为我们的shape类的成员变量area和perimeter是protected的,所以无法访问。
- 我们可以在Shape类中定义一个输出函数并采取friend字段。
- 我们却发现输出的流却像地址,我们回到我们的打印的模板,此时的T其实是Shape*,所以此时的arr的类型就是指针,所以输出的流便是地址。
我们可以额外再写一个T抽象函数专门针对指针类型 - 我们继续前进:修改shape类,添加一个虚拟函数,想要输出每个类的名字,同时每个子类都实现这个函数。但是我们会发现程序报错:
- 因为我们输出函数中的Shape变量前有const修饰,说明我们不能改变它的状态,所以我们在输出函数中调用name()函数是不可行的。
- 我们想要解决需要在shape类中对name()函数用const修饰。显式告诉编译器我们在函数中不会改变状态。
1 |
|
- 我们再回到这堂课的最初出发点:selection sort,我们现在想要根据面积和周长分别进行排序,那这样我们需要添加一个selection_sort函数和find_min函数,因为此时我们的接口多了一个自定义的比较函数。
- 在这里需要注意的是我们的自定义的比较函数不能直接访问Shape类的成员变量,我们需要在Shape类中定义get函数。
- 其实当我们定义好get函数后,我们可以将Shape类中的freind修饰的输出函数删除,我们的输出函数可以通过调用get函数而不需要访问Shape类的成员变量。
- 除了单独书写一个比较函数,我们还可以在主函数调用时直接在主函数中传入比较函数。
1 |
|
week 3
STL
What is STL
- C++的标准模板库的一部分
- 封装C++的数据结构与算法
- 包含:
- 容器:class templates,common data structures
- 算法
- 迭代器:泛化的指针,在容器与算法间打交道
Why should I use STL
- 节省时间与工作量
- 增加程序可读性
Containers
- 线性容器
- array(static),vector(dynamic)
- deque(double-ended queue)
- forward_list(signlely linked list),list(doubly linked list)
- 关联性容器(本质上是用红黑树)
- set(collection of unique keys)
- map(collection of key-value pairs)
- multiset,multimap
- Unordered associative
- hashed by keys
- unordered_set,unordered_map
- unordered_multiset,unordered_multimap
- Adaptors
- stack
- queue
- priority_queue
vector example
1 |
|
other containers
1 |
|
Algorithms
- works on a range defined as [first,last]
- for_each,find,count
- copy,fill,transform,replace,rotate
- sort,partial_sort,nth_element
- set_difference,set_union
- min_element,max_element
- accumulate,partial_sum
ex
1 |
|
iterators
- connect containers and algorithms
- 后面的课会讲到
pitfalls
access safety
- accessing an element out of range
- use push_back() for dynamic expansion
- preallocate with constructor
- reallocate with resize()
silent insertion
- map<>中如果没有对应的pair,可能悄悄添加
- 通常用count() or contains()(基于c++20)来检查
size() on list<>
- my_list.size() might cost linear time before C++11
- Constant time guaranteed:my_list.empty()
invalid iterator
- using invalid iterator
1
2
3
4
5
6
7list <int> L;
list <int>:: iterator li;
li=L.begin();
L.erase(li);
++li;//wrong
//我们需要重新调整
li=L.erase(li);
week 4
memory model
what are these variables?
1 |
|
分配位置
不同的变量介绍
- 全局变量(global)
- vars defined outside any functions
- can be shared btw .cpp files
- extern(用其他模块的全局变量)
3.1 extern is a declaration says there will be such a variable somewhere in the whole program
3.2 “such a” means the type and the name of the variable
3.3 global variable is a definition , the place for that variable - static
4.1 static global variable inhibits access from outside the .cpp file(只有在本模块使用)
4.2 so as the static function
4.3 static local variable keeps value between visits to the same function(存储与全局变量相同,并且第一次调用时初始化)
指针
1 |
|
- operators with pointers
- get address
- get the object
- call the function
- two ways to access
- string s;
1.1 s is the object itself
1.2 at this line,object s is created and initialized - string *ps;
2.1 ps is a pointer to an object
2.2 the object ps points to is not konwn yet
- string s;
Reference
Defining references
- references are a new data type in C++
- type& refname =name;
- for ordinary variable definitions
- an initial value is required
- type& refname;
- In parameter lists or member variables
- Binding defined by caller or constructor
1 |
|
Rules of references
- 引用变量创造时必须初始化
- 初始化建立了binding,并且不能再重新和另一个变量绑定
1 |
|
- 引用变量的本质就是给已经存在的变量多了个名字
- non-const的reference不能绑定表达式
1 |
|
Type restrictions
- No references to references
- No pointers to references,but reference to pointer is ok
1 |
|
- No arrays of references
Dynamically allocated memory
Dynamic memory allocation
- new expression
new int;
new Stash;
new int[10]; - delete expression
delete p;
delete [] p; - new与malloc的差异在于:new在动态分配内存的同时还通过构造函数初始化对象,我们下面的例子就说明了这点。
- 同时对于数组的删除,我们可以发现删除的顺序是从后往前删除的。
- 注意对于数组的删除采取 delete [] p;但是如果我们写delete p,只能删除第一个元素。
- new、delete和malloc、free不能混用。
1 |
|
- 下面的例子告诉我们new出来的东西一定要及时删干净,否则迟早占用完内存。并且内存不能释放两次。
- 还需要区分被释放的空间和零指针NULL没有任何关系。也就是说NULL也占据了动态空间的。
1 |
|