赞
踩
局部静态变量
**特点:静态全局变量
静态函数
类的静态成员
类的静态函数
Static_cast:
Dynamic_cast:
只能用于含有虚函数的类
,上行转换和static_cast没有区别,都是安全的;下行转换时,dynamic_cast会检查转换类型,相比static_cast更安全。仅用于指针和引用的转换。还有void *的转换
。Const_cast:
Reinterpret_cast:
为什么不使用C的强制转换:
指针在运行时可以改变所指向的值,而引用一旦与某个对象绑定后就不再改变。意思是:指针可以被重新赋值以指向另一个对象,但是引用则总是在初始化时被指定的对象,以后不能改变,但是指向的内容可以改变。(下面是这个规则的理解)
由于 C++ 语言没有自动内存回收机制,程序员每次 new 出来的内存都要手动 delete。程序员忘记 delete,流程太复杂,最终导致没有 delete,异常导致程序过早退出,没有执行 delete 的情况并不罕见,导致内存泄漏。使用智能指针可以很大程度避免这个问题,因为智能指针本身就是一个类,当超出了类的作用域,类会自动调用析构函数自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间,不需手动释放。
auto_ptr:(c++98的方案,c++11已经抛弃)
野指针,是指向不可用内存区域的指针,指向一个已删除的对象或者未申请访问受限内存区域的指针。
造成野指针的原因主要有三种:
1、指针变量没有被初始化。
2、指针指向的内存被释放了,而指针本身没有置NULL。
3 、指针超过了变量的作用范围。
将可能会被继承的父类的析构函数设置为虚函数,可以保证基类指针指向派生类对象时,释放基类指针也可以释放掉子类的空间,防止内存泄漏。
对于下图左:基类指针指向派生类对象时,这是因为在调用普通函数时,在编译期间已经确定了它所要调用的函数(静态绑定),因为a是A*类型,因此只会调用基类的析构函数。 对于下图右,基类析构使用虚函数,这是因为当我们把基类析构函数定义为虚函数时,在调用析构函数时,会在程序运行期间根据指向的对象类型到它的虚函数表中找到对应的虚函数(动态绑定),此时找到的是派生类的析构函数,因此调用该析构函数;而调用派生类析构函数之后会再调用基类的析构函数,因此不会导致内存泄漏。
纯虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。
虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组.而对象的隐藏成员–虚拟函数表指针是在运行期–也就是构造函数被调用时进行初始化的,编译器会把虚函数表的首地址赋值给虚函数表指针,这是实现多态的关键。
也可以用类的构造函数。
可以使用const或define
将成员函数声明为const,则该函数不允许修改类的数据成员。只有被声明为const的成员函数才能被一个const类对象调用,而非const对象可以访问任意的成员函数,包括const成员函数
线程中函数堆栈默认是1M,Linux下默认是8M ulimit –s
可查看 这些都可以修改。
extern "C"的主要作用就是为了能够正确实现C++代码调用其他C语言代码。加上extern "C"后,会指示编译器这部分代码按C语言的进行编译,而不是C++的。由于C++支持函数重载,因此编译器编译函数的过程中会将函数的参数类型也加到编译后的代码中,而不仅仅是函数名;而C语言并不支持函数重载,因此编译C语言代码的函数时不会带上函数的参数类型,一般只包括函数名。
EBP 基址指针,是保存调用者函数的地址,总是指向函数栈栈底,ESP被调函数的指针,总是指向函数栈栈顶。
Select函数可以实现I/O的多路复用,用于监视文件描述符的状态,fd_set中的每一bit可以对应一个文件描述符fd,先将需要监控的描述符对应的bit位置1,然后将其传给select,当有任何一个事件发生时,select将会返回所有的描述符,需要应用程序自己遍历检查哪个描述符上有事件发生,效率有点低,并且不断在内核态和用户态进行描述符的拷贝,开销有点大。
注意事项:每次调用select之前,timeout都用重新设置。由于select()修改其文件描述符集,如果调用在循环中使用,则必须在每次调用之前重新初始化这些集。
Epoll
首先epoll_create创建一个epoll对象,然后使用epoll_ctl对这个对象进行操作,把需要监控的描述添加进去,这些描述将会以epoll_event结构体形式组成一颗红黑树,接着阻塞在epoll_wait,进入大循环,当某个fd上有事件发生时,内核将会把对应的结构体放入到一个链表中,返回有事件发生的链表。
目前的常用的IO复用模型有三种:select,poll,epoll。
父进程产生子进程,使用fork拷贝出来的一个父进程的副本,此时只拷贝了父进程的页表,两个进程都读同一块内存,当有进程写的时候,使用写实拷贝机制分配内存,fork从父进程返回子进程的pid,从子进程返回0.;exec函数可以加载一个elf文件去替换父进程,从而父进程和子进程就可以运行不同的程序,exec执行成功,则子进程从新的进程开始运行,无返回值;如果执行失败,则返回-1;调用了wait的父进程将会发生阻塞,直到有子进程的状态改变,执行成功返回0,错误返回-1。
场景:当频繁调用小函数时,为了节省函数调用的开销,可以使用内联函数。
C++的多态是通过覆盖实现的,即父类的函数被子类覆盖了!
父类的该函数为虚函数,告诉父类的指针/引用,你调用这个函数的时候必须看一看你绑定的对象到底是哪个类的对象,然后去那个类里调用该函数!
char str1[]="12345678"; 后面有一个看不见的‘\0’
char str2[]={'1','2','3','4','5','6','7','8'};
char str3[]={'1','2','3','\0','5','6','7','8'};
str1是一个字符数组,由字符串"12345678"进行初始化。由于"12345678"含有一个结尾字符'\0',所以str1数组共有9个字符。 因此sizeof(str1)=9。
str2也是一个字符数组,它的长度由'1','2','3','4','5','6','7','8'8个字符初始化,并没有指明零字符。 因此sizeof(str2)=8。
str3同样由8个字符初始化,因此sizeof(str3)=8。
strlen函数只计算字符串中不含零的字符个数。因此:strlen(str1)=8。
而由于str2中最后一个字符不包含零,所以,str2不是一个有效的字符串, 因此strlen(str2)不确定。
而对于字符数组str3,在第4个字符为'\0',所以作为一个字符串,在此处结尾。所以strlen(str3)=3
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。