哪些函数不能是虚函数,为什么?
static,构造函数,inline不能是虚函数;
构造函数为什么不能是:
1.虚函数的调用需要使用虚函数指针和虚函数表,虚函数指针和虚函数表都在对象的内存空间中,但是在调用构造函数的时候,对象还没创建好,内存空间还不存在;
2.在调用构造函数时,对象还没创建好,不知道其创建的对象类型,而虚函数是需要在在运行时确定了、对象类型的;
static为什么不能是:
1.static是针对整个类的,而不是针对某个对象的;
2.static函数没有this指针,而虚函数需要用this指针指向vptr;
inline为什么不能是:
inline函数是在编译的时候复制展开到调用的位置,需要知道明确的对象类型,而虚函数在运行期间才知道都对象类型,编译期间不知道;
关键字new的相关问题:
有了new/delete为什么还要有malloc/free:
我当时回答的malloc更快,因为new还要调用构造函数;
new可以重载吗:
new是关键字不能重载,调用operator new()分配空间,operator new()是函数,可以重载;(我一开始说的new可以重载,后面反应过来是operator new)
operator new被重载返回值必须是void*, 第一个形参必须是size_t,如果还传入其他参数就变成placement new,
placement new并不分配内存,只是返回已经分配好的一段内存的指针,
void* operator new(std::size_t size, void* ptr)
可以通过placement new实现批量new,一次性new很多对象出来,注意要先调用每个对象的析构函数之后再使用
delete;
STL中map[]和insert的区别:
增添元素时,map[]会默认构造一个string作为你的value,再将真实的value赋值给他,多了一次默认构造得操作;
更新元素时,insert每次都会生成一个新的pair,事后还要析构此对象;
宏函数和带参数的函数区别:
1.函数调用时,先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换。
2.函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
3.对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。
4.调用函数只可得到一个返回值,而用宏可以设法得到几个结果。
5.使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调用不使源程序变长。
6.宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。
2.函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
3.对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。
4.调用函数只可得到一个返回值,而用宏可以设法得到几个结果。
5.使用宏次数多时,宏展开后源程序长,因为每展开一次都使程序增长,而函数调用不使源程序变长。
6.宏替换不占运行时间,只占编译时间;而函数调用则占运行时间(分配单元、保留现场、值传递、返回)。
有栈协程和无栈协程:
有栈协程的一般实现是:在内存中给每个协程开辟一个栈内存,当协程挂起时会将它的运行时上下文(即栈空间)从系统栈中保存至其所分配的栈内存中,当协程恢复时会将其运行时上下文从栈内存中恢复至系统栈中。
无栈协程通常是 基于状态机或闭包 来实现。无栈协程不需要修改调用栈,也无需额外的内存来保存调用栈,因此它的开销会更小。但是,相比于保存运行时上下文这种实现方式,无栈协程的实现还是存在比较多的限制,最大缺点就是,它无法实现在任意函数调用层级的位置进行挂起。
c++如何实现反射: C++编译器完全可以将类型信息与虚函数表一起保存,在现有虚函数表里面附加类型信息,然后可以通过对象的虚函数表针对找到对象的类型信息。这种方案不会破坏C++原有的对象内存模型,只是拓展了虚函数表的功能
全部评论
(5) 回帖