程设语言部分笔记

断更了好久……

其实也说不清在忙什么……

莫名其妙的……

雾:下文内含大量typo(拼音输入法)


OpenJudge - B:按距离排序 给struct重载() 来当比较器传给std::sort

OpenJudge - G:你真的搞清楚为啥 while(cin >> n) 能成立了吗?

1
2
3
operator bool() {
// 重载强制类型转换
}

修改指针一定要小心,尤其是模板里面 *a = *b 注意指针指向的地址是否变了 是否只改变了值

OpenJudge - C:山寨版istream_iterator
operator *() 重载解引用运算符 operator ++(int) 是后缀自增运算符

OpenJudge - E:很难蒙混过关的CArray3d三维数组模板类

写得很痛苦,的确没有蒙混过关,还是应该老实的……

  • 建议做法:
  1. a[i][j][k] 这个表达式的第一个[]返回一个内部类的对象,该内部类也重载了[],且返回值为指针。
  2. 必要时需重载对象到指针的强制类型转换运算符

OpenJudge - F:我自己的 ostream_iterator

刚开始一直在想怎么让他赋值进去就直接能输出,后来发现实际上是后面有一个++的过程,++的时候输出就好了。
然后再就是*x=*a重载的是*运算符不是等号= =

OpenJudge - A:List

简直惨痛。。。 merge自己到自己的操作要忽略掉就好了= = 果然还是应该写对拍

OpenJudge - F:冷血格斗场

听说是当年pkusc的题,就是找lowerbound 然后再找前面的一个 比较比较就好了

没考虑到的地方是可能lowerbound的前面找到的那个并不是id最小的,要再lowerbound一下= =

OpenJudge - 08:编程填空:维护平面点

OpenJudge - H:编程填空:数据库内的学生信息

比较器的写法

1
2
3
4
5
6
7
8
9
template <class T>
struct Greater {
bool operator() (const T& x, const T& y) const {
return x > y;
}
typedef T first_argument_type;
typedef T second_argument_type;
typedef bool result_type;
};

upd:重写了 后三个typedef 不是必须的
OpenJudge - 11:编程填空:数据库内的学生信息

太难了= =

static的初始化方式

printf – %x 十六进制


期中复习

常引用:不是引用的内容不能修改,是不能通过常引用修改
const T 或者 const T &类型不能用来初始化 T&类型,除非经过了强制类型转换
调用内联函数的语句前必须已经出现内联函数的定义(整个函数体),不能只有声明
同名函数只有参数表不同才算是重载,两个同名函数的参数表相同而返回值不同不是重载,是重复定义
new分配的空间一定要delete释放,否则程序运行结束后也不会被系统收回
一个string对象的大小(sizeof)是固定的(在不同编译器中并不相同,与字符串长度无关)
string对象中只存放地址和其他信息
大写字母ASCII码小于小写字母
struct默认公有,class默认私有
局部变量存储空间是动态分配在栈中的
CTest* pArray[3] = {new CTest(4), new CTest(1, 2)}; 只生成了两个对象,第三个没有生成
复制构造函数的参数一般用const引用,这样既能以常量对象,也能以非常量对象作为参数
函数的参数对象以及作为函数返回值的对象,在消亡时也会引发析构函数调用

1
2
3
4
5
6
7
8
9
10
CDemo::CDemo(int a, int b) {
// 构造函数
}
CDemo dl;
CDemo Test() { // 返回值是临时对象
foo();
return dl;
}
CDemo d4;
d4 = 6; // 这里6先被转换成临时对象,然后再赋值。语句执行完毕后临时对象消亡,调用析构函数

并非所有对象生成的时候都通过上面的构造函数初始化,作为参数和返回值的时候是调用复制构造函数,需要另外再写
不能通过对常量对象调用普通成员函数,但是可以调用const的
两个成员函数的名字和参数表相同,但是一个const,另一个不是,算重载
封闭类生成的时候先执行所有成员对象的构造函数,再执行封闭类自己的构造函数
消亡的时候是先执行封闭类的析构函数,后执行成员对象的。
常量型成员变量和引用型必须要在构造函数的初始化列表中初始化
友元函数内部可以访问该类对象的private
不能吧其他类的私有成员函数声明为友元
交叉调用的时候允许写一个提前声明class s;但是在定义出现之前,不允许任何会导致该类对象被生成的语句。使用该类的指针或者引用是没有问题的
可以声明另一个类是自己的友元
友元关系不能传递
类的非内联成员函数的函数体只能出现在某一个.cpp文件中,不能放在头文件中被多个.cpp文件包含,否则链接时会发生重复定义的错误
如果编写了构造函数,则编译器不自动生成默认构造函数,一个类不一定会有默认(无参)构造函数,但是一定会有复制构造函数
=只能重载为成员函数
在delete之前判断是否是NULL
注意赋值给自己的时候的指针的处理
参数os只能是ostream的引用,而不能使ostream对象,是因为ostream的复制构造函数是私有的,不能生成参数对象
类型强制转换运算符是单目运算符,只能被重载为成员函数 operator double() {}
++a或者--a前置:CDemo& operator ++();
a++或者a--后置:CDemo operator ++(int);
运算符重载不改变优先级
不能被重载的运算符:. .*(成员指针访问运算符) :: ?: sizeof
重载() [] ->或者 赋值=时,只能重载为成员函数
派生类的成员函数只能访问所作用的那个对象(this指向的)的基类保护成员,不能访问其他基类对象的基类保护成员
如果一个派生类对象使用默认复制构造函数初始化的,那么他内部包含的基类对象也要用基类的复制构造函数初始化
封闭类类似
派生类对象生成的时候,先从上至下执行所有基类的构造函数,再按照成员对象的定义顺序执行各个成员对象的构造函数,最后执行自身的
消亡时,先执行自身的,后面与够早的次序相反
如果是public派生,派生类对象也是基类对象,如果是private或者protected,就不成立
多态的函数调用语句被称为是动态联编
虚函数表的地址在对象存储空间的最前端
成员函数(静态成员函数、构造函数、析构函数除外)中调用其他虚成员函数是多态的
析构函数和构造函数中调用的虚函数不是多态
只要基类中的某个函数被声明成虚函数,则派生类中的同名、同参数表的成员函数及时前面没写virtual也是虚函数
虚析构函数:只要基类的析构函数是虚函数,那么派生类的析构函数不论是否用virtual声明,都是虚析构函数
一个类如果定义了虚函数,则最好将析构函数也定义成虚函数
独立的抽象类的对象不存在,但是被包含在派生类对象中的抽象类的对象是可以存在的
抽象类的成员函数内可以调用纯虚函数,但是在构造函数或析构函数内部不能
cerr clog 不能被重定向
cerr 不使用缓冲区 clog 使用
while (cin >> n) 是因为把ostream到bool的转换重载了

顺序容器:vector, deque, list
关联容器:set, multiset, map, multimap
容器适配器:stack, queue, priority_queue
rend():只想容器中的第一个元素前面的位置的反向迭代器

1
for (auto it = v.rbegin(); it != v.rend(); ++it);

容器 迭代器功能
vector 随机
deque 随机
list 双向
set/ multiset 双向
map/ multimap 双向
stack 不支持迭代器
queue 不支持迭代器
priority_queue 不支持迭代器
1
2
3
4
5
ostream_iterator<int> output(cout," ");
copy (v.begin(), v.end(), output);
std::set_union(v1.begin(), v1.end(), v2.begin(), v2.end(), std::back_inserter(dest1));

考完试:

1
2
3
4
5
6
7
template<class T, int sz>
class A {
public:
static int c;
};
template < > int A <int, 40>::c = 0;
template < > int A <int, 50>::c = 1;

const算不算重载
什么时候需要在初始化列表里初始化