2018年8月1日21:52:37 —— 继承
1、派生类不能继承的几个东西
一个派生类继承了所有的基类方法,但下列情况除外:
基类的构造函数、析构函数和拷贝构造函数。
基类的重载运算符。
基类的友元函数。
2、继承类型
Class A{
}
class B: public/protected/private A{
}
B可以用 public protected private三种修饰符来继承A。
如果用public,那么A的public方法在B继承后仍然是public,protected仍然是protected
如果用protected,那么A的public方法在B继承后变成 protected,protected仍然是protected如果用private,那么A的public方法和protected在B继承后都变成private
2018年8月3日17:05:07 —— 异常
1、异常规范
函数后面添加throw(xxx)就是异常规范,比如
void foo() throw(){} // 这代表foo里面不会产生异常
void foo() throw(string, int){} // 代表foo里面会产生string 和 int类型的异常
如果函数产生了异常规范意外的异常,比如foo里面throw double(1.0),如果foo里面没有try catch处理double类型的异常,程序会崩溃。
函数throw的异常类型如果和异常规范中定义的不同,也不允许进行类型转换,比如foo中throw short(1)是不能转换成int型异常的(同样可能引起程序崩溃)。
2、一个常驻内存的异常直到该异常的最后一个catch子句退出时,它才销毁。因为可能被重新throw
3、把“catch子句的异常对象”定义成引用的一个原因是避免大对象拷贝,另一个原因是,确保能正确地调用与异常类型相关联的虚拟函数。
2018年8月4日20:23:12 —— 嵌套类
1、外围类不能访问嵌套类的private成员(比如在外围类的方法中),除非在嵌套类里面将外围类声明成friend
2、嵌套类可以访问外围类的私有成员,至少在我的ubuntu上用g++编译是可以的。
2018年8月6日21:05:55 —— 模板类
1、模板类的嵌套类自动成为一个模板类
2018年8月7日17:41:15 —— 函数模板
1、用函数实参类型决定模板实参类型的过程,叫做“模板实参推演”
注意,函数的返回值是不参与模板实参推演的。
2、“显式模板推演”和“显式实例化声明”的区别
显式模板推演:是在调用模板函数的时候,显式制定模板类型,比如sum<int, int, int>(1,2,3)
显式实例化声明:是在声明模板类的时候指示具体的模板参数类型,比如:
template<> int sum<double, float>
2018年8月8日14:04:02 —— 类继承和子类型
1、多态
从基类指针或引用操纵多个类型的能力叫做多态
2、动态绑定
在运行时刻解析出需要调用的函数,这个解析过程叫动态绑定。也就是说,不运行就不知道具体的类是什么,只有运行的时候知道了具体的类才能执行对应的函数。
动态绑定是通过虚拟函数机制实现的。
2018年8月11日17:03:47 —— 派生类的构造顺序
1、基类构造函数
2、派生类里的类成员对象构造函数,顺序和声明顺序相同,注意,和初始化列表中的顺序无关
3、派生类自己的构造函数
注意:派生类的构造函数一般使用初始化列表来初始化基类中的成员,如果直接给基类成员赋值会造成紧耦合,以后基类加减成员都不方便
4、每个派生类都不许提供自己的构造函数,基类的构造函数是不会被继承的
5、基类的析构函数一般声明成virtual的,并且要再public标签里面。
因为:
1》声明成virtual才可以通过基类指针或引用多态地调用子类的析构函数,否则没有多态只能调用基类自身的析构函数。
2》放在public里面,是因为delete base_pointer的时候直接访问的还是基类的析构函数,如果不是public就无权访问了。
6、构造函数和析构函数中不能调用virtual函数。
因为,创建一个子类时会先调用基类构造函数,这个时候构造出来的仅仅是基类的子类型,子类还没构造出来,如果virtual函数动态调用到了子类的函数,但子类的virtual函数使用了还没初始化的变量,这就会导致程序崩溃。
如果一个基类指针指向子类,在销毁基类指针时,会先调用子类析构函数,等到执行基类析构函数时,如果调用virtual函数动态调用了子类的函数的话,那么调用的就是已经销毁的资源,同样会导致崩溃。
2018年8月14日17:48:40 —— 虚函数
类的成员函数如果是virtual,但不是纯虚函数的话,那么这个虚函数一定要有定义
2018年8月15日16:23:43 —— 按成员初始化和复制
比如
NameQuery folk(“folk”)
NameQuery music = folk
会发生如下过程:
1、查看类是否有显示拷贝构造函数,如果有直接调用并结束,否则进入2
2、查看是否含有基类子对象,如果有,则对子对象递归地按照从1的步骤判断,否则按成员声明顺序赋值。如果成员是自定义类对象,同样递归按照步骤1判断,如果成员是内建类类型则直接调用拷贝构造函数,如果是非类类型,直接拷贝值。
2018年8月15日21:34:46 —— 继承下的类域
1、一个类两个花括号中间的部分就是类域
2、一个派生类的类域直接嵌套再基类的类域当中
3、名字解析,如果编译器没有在派生类域中找到,则会在基类类域中找,并依次向上查找外围类域
2018年8月16日12:22:43 —— 派生
1、内置类型不能再被派生,比如
class A: public int{}
会导致编译时刻错误
2018年8月16日17:08:12 —— dynamic_cast
当需要使用派生类的特性,而这个特性又没出现在基类中时经常用
集合求交
https://blog.youkuaiyun.com/weiwenhp/article/details/8691463
set<int> one;
one.insert(11);
one.insert(22);
one.insert(33);
set<int> two;
two.insert(11);
two.insert(44);
two.insert(55);
vector<int> result;
result.resize( one.size() + two.size() ); //result是用来保存one和two的交,并,差集的.自然要保定它的大小.要能装得下one,two两者元素之和.
vector<int>:iterator retEndPos; //这是那些算法函数返回的结果
retEndPos = set_intersection( one.begin(), one.end(), two.begin(), two.end() ,result.begin()); result.resize( retEndPos - result.begin() ) ; //重新调整result的大小,使其大小刚好等于并集元素个数.
字符串转换成数字
1.c++11标准增加了全局函数std::to_string: string to_string (int val); string to_string (long val); string to_string (long long val); string to_string (unsigned val); string to_string (unsigned long val); string to_string (unsigned long long val); string to_string (float val); string to_string (double val); string to_string (long double val);
push_back可以用emplace_back替代,后者效率更高
字典 map 初始化,查看其中是否包含key
map<int, string> ID_Name = { { 2015, "Jim" }, { 2016, "Tom" }, { 2017, "Bob" } }; ID_name.count(2015) // >0 ID_name.count(8888) // ==0 ID_name.find(8888) == ID_name.end() // true
判断map中是否包含key
1 if(m.count(key)>0) 2 { 3 return m[key]; 4 } 5 return null;
字符串查找
position = s.find("jk"); if (position != s.npos) //如果没找到,返回一个特别的标志c++中用npos表示,我这里npos取值是4294967295, { cout << "position is : " << position << endl; }
map 遍历
std::unordered_map<std::string, std::string> u = { { "RED", "#FF0000" }, { "GREEN", "#00FF00" }, { "BLUE", "#0000FF" } }; // Iterate and print keys and values of unordered_map for (const auto& n : u) { std::cout << "Key:[" << n.first << "] Value:[" << n.second << "]\n"; }
unordered_set 查找
#include <iostream> #include <unordered_set> using namespace std; int main() { unordered_set<string> v = {"aaa","bbb"}; unordered_set<string> v2; cout <<v.size()<<endl; cout <<v2.size()<<endl; if (v.find("aa") == v.end()) cout<<"xxxx"<<endl; else cout<<"yyyy"<<endl; return 0; }