目录
C++基础
继承/派生
注意问题:
1.用一个类做基类,相当于声明一个该类的对象,所以一定要有类的定义,只有声明是不行的
class employee; // 只有声明,没有定义
class Manager:public Employee{}; // 不行,没有Employee的定义
2.派生类可以使用基类中所有public和protected的成员。
3.类对象的构造是自下向上的,首先是基类,而后是成员,再后才是派生类本身。类对象的销毁正好相反。
4.构造函数和析构函数无法继承,因此在派生类中需要自己对基类的构造函数进行调用。
5.构造函数原则:
子类没有定义构造方法,则调用父类的无参数构造方法
子类定义了构造方法(不论无参数还是带参数),若未显示调用父类的构造方法,首先执行父类无参数的构造方法,然后执行自己的构造方法。
子类定义了构造方法(不论无参数还是带参数),若未显示调用父类的构造方法但父类只定义了有参构造函数,则会出错(如果父类只有有参数的构造方法,则子类必须显示调用此带参构造方法)。
子类在构造函数中显示调用父类带参数的构造方法,需要初始化父类成员对象的方法。
虚函数
虚函数与重载关系:
1、在派生类中重载一个虚函数,要求函数名、返回类型、参数个数、参数类型以及参数的顺序都与基类中原型完全相同,不能有任何的不同。
2、一般的函数重载,只要函数名相同即可,函数的返回类型及所带的参数可以不同。
规则:
1、只有成员函数才能声明为虚函数。因为虚函数仅适用于有继承关系的类对象,所以普通函数不能声明为虚函数。
2、虚函数必须是非静态成员函数。因为静态成员函数不受限于某个对象。
3、内联函数不能声明为虚函数。因为内联函数不能在运行中动态确定其位置。
4、构造函数不能声明为虚函数。多态是指不同的对象对同一消息有不同的行为特性。虚函数作为运行过程中多态的基础,主要是针对对象的,而构造函数是在对象产生之前运行的,因此,虚构造函数是没有意义的。
5、析构函数可以声明为虚函数。析构函数的功能是在该类对象消亡之前进行一些必要的清理工作,析构函数没有类型,也没有参数,和普通成员函数相比,虚析构函数情况略为简单些。
并发编程
三大性质总结:原子性,有序性和可见性:
https://www.jianshu.com/p/cf57726e77f2
STL
memcpy和memmove区别
https://www.cnblogs.com/luoquan/p/5265273.html
模板
模板是C++支持参数化多态的工具,使用模板可以使用户为类或者函数声明一种一般模式,使得类中的某些数据成员或者成员函数的参数、返回值取得任意类型。
模板是一种对类型进行参数化的工具;
通常有两种形式:函数模板和类模板;
函数模板针对仅参数类型不同的函数;
类模板针对仅数据成员和成员函数类型不同的类。
使用模板的目的就是能够让程序员编写与类型无关的代码。比如编写了一个交换两个整型int 类型的swap函数,这个函数就只能实现int 型,对double,字符这些类型无法实现,要实现这些类型的交换就要重新编写另一个swap函数。使用模板的目的就是要让这程序的实现与类型无关,比如一个swap模板函数,即可以实现int 型,又可以实现double型的交换。模板可以应用于函数和类。下面分别介绍。
注意:模板的声明或定义只能在全局,命名空间或类范围内进行。即不能在局部范围,函数内进行,比如不能在main函数中声明或定义一个模板。
http://www.cnblogs.com/gw811/archive/2012/10/25/2738929.html
内联函数
https://www.cnblogs.com/msdn1433/p/3569176.html
(1)什么是内联函数? 内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内。 (2)为什么要引入内联函数? 当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题。另外,前面我们讲到了宏,里面有这么一个例子: #define ABS(x) ((x)>0? (x):-(x)) 当++i出现时,宏就会歪曲我们的意思,换句话说就是:宏的定义很容易产生二意性。 我们可以看到宏有一些难以避免的问题,怎么解决呢?前面我们已经尽力替换了。 下面我们用内联函数来解决这些问题。 (3)为什么inline能取代宏? 1、 inline 定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高。 2、 很明显,类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。 3、 inline 可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。 (4)内联函数和宏的区别? 内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。内联函数与带参数的宏定义进行下比较,它们的代码效率是一样,但是内联欢函数要优于宏定义,因为内联函数遵循的类型和作用域规则,它与一般函数更相近,在一些编译器中,一旦关上内联扩展,将与一般函数一样进行调用,比较方便。 (5)什么时候用内联函数? 内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把这些读写成 员函数定义成内联函数的话,将会获得比较好的效率。 Class A { Private: int nTest; Public: int readtest() { return nTest;} void settest(int I) { nTest=I; } } (6)如何使用内联函数? 我们可以用inline来定义内联函数。 inline int A (int x) { return 2*x; } 不过,任何在类的说明部分定义的函数都会被自动的认为是内联函数。 (7)内联函数的优缺点? 我们可以把它作为一般的函数一样调用,但是由于内联函数在需要的时候,会像宏一样展开,所以执行速度确比一般函数的执行速度要快。当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。(换句话说就是,你使用内联函数,只不过是向编译器提出一个申请,编译器可以拒绝你的申请)这样,内联函数就和普通函数执行效率一样了。 (8)如何禁止函数进行内联? 如果使用VC++,可以使用/Ob命令行参数。当然,也可以在程序中使用 #pragma auto_inline达到相同的目的。 (9)注意事项: 1.在内联函数内不允许用循环语句和开关语句。 2.内联函数的定义必须出现在内联函数第一次被调用之前。 这涉及一个效率问题。记住,调用函数的开销是很大的,所谓的空间开销是指调用函数前, 先要将原来的函数保存在寄存器(占用寄存器空间)里面,并在调用结束后恢复。调用函 数时,还要复制实参(占用内存空间)。如果被调用函数一旦调用频繁,就会花费很多空 间。如果你有一段“短小而频繁调用的函数”,内联是个不错的选择。 “如果含有复杂的分支或循环结构,我使用inline会有什么后果?” 事实上,所谓内联,是编译器将内联函数在函数调用点上展开函数代码。例如 inline int small(int a,int b) { return a < b ? a : b ; } cout << small ( a, b ) << endl ; 等同于 cout << (a < b ? a : b) << endl; 编译器会将函数调用语句转换为函数代码, 再进行编译。inline只是你给编译器提一个建议,希望它将函数内联,至于它会不会执行就不一 定了。 基本上复杂的函数它是不会同意的,就算同意了,也只会使你的编译变得更将浪费时间, 而执行速度得不到什么提升。还有,一些编译器是不会通过含有递归的内联函数的。 记住 ,短小而且反复调用的函数进行内联就可以了。