c++提供的可有效分配对象空间的运算符是_C/C++经典面试题

9caf4dae97f68864b2ec010259b0334a.png

面试题 13:C++的空类有哪些成员函数  缺省构造函数。  缺省拷贝构造函数。  缺省析构函数。  缺省赋值运算符。  缺省取址运算符。  缺省取址运算符 const。 注意:有些书上只是简单的介绍了前四个函数。没有提及后面这两个函数。但后面这两个函数也是 空类的默认函数。另外需要注意的是,只有当实际使用这些函数的时候,编译器才会去定义它们。 5 面试题 14:谈谈你对拷贝构造函数和赋值运算符的认识 拷贝构造函数和赋值运算符重载有以下两个不同之处: (1)拷贝构造函数生成新的类对象,而赋值运算符不能。 (2)由于拷贝构造函数是直接构造一个新的类对象,所以在初始化这个对象之前不用检验源对象 是否和新建对象相同。而赋值运算符则需要这个操作,另外赋值运算中如果原来的对象中有内存分配要 先把内存释放掉 注意:当有类中有指针类型的成员变量时,一定要重写拷贝构造函数和赋值运算符,不要使用默认 的。

面试题 15:用 C++设计一个不能被继承的类 template class A { friend T; private: A() {} ~A() {} }; class B : virtual public A { public: B() {} ~B() {} }; class C : virtual public B { public: C() {} ~C() {} }; void main( void ) { B b; //C c; return; } 注意:构造函数是继承实现的关键,每次子类对象构造时,首先调用的是父类的构造函数,然后才 是自己的。

面试题 16:访问基类的私有虚函数 写出以下程序的输出结果: #include class A 6 { virtual void g() { cout << "A::g" << endl; } private: virtual void f() { cout << "A::f" << endl; } }; class B : public A { void g() { cout << "B::g" << endl; } virtual void h() { cout << "B::h" << endl; } }; typedef void( *Fun )( void ); void main() { B b; Fun pFun; for(int i = 0 ; i < 3; i++) { pFun = ( Fun )*( ( int* ) * ( int* )( &b ) + i ); pFun(); } } 输出结果: B::g A::f B::h 注意:本题主要考察了面试者对虚函数的理解程度。一个对虚函数不了解的人很难正确的做出本题。 在学习面向对象的多态性时一定要深刻理解虚函数表的工作原理。

面试题 17:简述类成员函数的重写、重载和隐藏的区别 (1)重写和重载主要有以下几点不同。  范围的区别:被重写的和重写的函数在两个类中,而重载和被重载的函数在同一个类中。  参数的区别:被重写函数和重写函数的参数列表一定相同,而被重载函数和重载函数的参数列表一 定不同。  virtual 的区别:重写的基类中被重写的函数必须要有 virtual 修饰,而重载函数和被重载函数可以被 7 virtual 修饰,也可以没有。 (2)隐藏和重写、重载有以下几点不同。  与重载的范围不同:和重写一样,隐藏函数和被隐藏函数不在同一个类中。  参数的区别:隐藏函数和被隐藏的函数的参数列表可以相同,也可不同,但是函数名肯定要相同。 当参数不相同时,无论基类中的参数是否被 virtual 修饰,基类的函数都是被隐藏,而不是被重写。 说明:虽然重载和覆盖都是实现多态的基础,但是两者实现的技术完全不相同,达到的目的也是完 全不同的,覆盖是动态态绑定的多态,而重载是静态绑定的多态。

面试题 18:简述多态实现的原理 编译器发现一个类中有虚函数,便会立即为此类生成虚函数表 vtable。虚函数表的各表项为指向对 应虚函数的指针。编译器还会在此类中隐含插入一个指针 vptr(对 vc 编译器来说,它插在类的第一个位 置上)指向虚函数表。调用此类的构造函数时,在类的构造函数中,编译器会隐含执行 vptr 与 vtable 的 关联代码,将 vptr 指向对应的 vtable,将类与此类的 vtable 联系了起来。另外在调用类的构造函数时, 指向基础类的指针此时已经变成指向具体的类的 this 指针,这样依靠此 this 指针即可得到正确的 vtable,。 如此才能真正与函数体进行连接,这就是动态联编,实现多态的基本原理。 注意:一定要区分虚函数,纯虚函数、虚拟继承的关系和区别。牢记虚函数实现原理,因为多态 C++面试的重要考点之一,而虚函数是实现多态的基础。

面试题 19:链表和数组有什么区别 数组和链表有以下几点不同: (1)存储形式:数组是一块连续的空间,声明时就要确定长度。链表是一块可不连续的动态空间, 长度可变,每个结点要保存相邻结点指针。 (2)数据查找:数组的线性查找速度快,查找操作直接使用偏移地址。链表需要按顺序检索结点, 效率低。 (3)数据插入或删除:链表可以快速插入和删除结点,而数组则可能需要大量数据移动。 (4)越界问题:链表不存在越界问题,数组有越界问题。 说明:在选择数组或链表数据结构时,一定要根据实际需要进行选择。数组便于查询,链表便于插 入删除。数组节省空间但是长度固定,链表虽然变长但是占了更多的存储空间。

面试题 20:怎样把一个单链表反序 (1)反转一个链表。循环算法。 List reverse(List n) { if(!n) //判断链表是否为空,为空即退出。 { return n; } list cur = n.next; //保存头结点的下个结点 list pre = n; //保存头结点 list tmp; 8 pre.next = null; //头结点的指针指空,转换后变尾结点 while ( NULL != cur.next ) //循环直到 cur.next 为空 { tmp = cur; //实现如图 10.3—图 10.5 所示 tmp.next = pre pre = tmp; cur = cur.next; } return tmp; //f 返回头指针 } (2)反转一个链表。递归算法。 List *reverse( List *oldList, List *newHead = NULL ) { List *next = oldList-> next; //记录上次翻转后的链表 oldList-> next = newHead; //将当前结点插入到翻转后链表的开头 newHead = oldList; //递归处理剩余的链表 return ( next==NULL )? newHead: reverse( t, newHead ); } 说明:循环算法就是图 10.2—图 10.5 的移动过程,比较好理解和想到。递归算法的设计虽有一点难 度,但是理解了循环算法,再设计递归算法就简单多了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值