C++自问自答

1.为什么派生层次上的类,同一个虚函数在各个类的虚表中的位置一样?
   
    因为:对虚函数的调用是通过虚指针+偏移地址构成,由于对虚函数的调用都是通过这种方式,所以对同一个虚函数的偏移值就必须相同。

2.为防止对象切片有什么办法?
 
   可以将基类定义为纯虚类

3.为什么构造函数里面的虚机制不起作用?

a.如果构造函数调用层次上,中间构造函数调用的虚函数属于派生类,由于派生类为初始化完成,所以会有问题。
  b.调用层次上的每一个构造函数,都会使虚指针指向该构造函数所属的类的虚表,而对象最终的虚指针是由最后调用的构造函数决定(辈分最小的类),如果在中间层次的构造函数调用虚函数,由于当前构造函数设置的虚指针是指向这个类的虚表,所以调用的虚函数还是自己的函数。

4.为什么纯虚析构函数必须有函数体?

因为,基类的析构函数总会被子类的析构函数调用,如果没有函数体,就不知道该怎么析构一个纯虚类。

5.如果一个派生类没有重定义基类的纯虚函数,会发生什么?

该派生类不能实例化。

6.为什么在析构函数中的虚机制不起作用。
  
    因为虚函数归属的类可能已经被删除。

7.为什么在使用dynamic_cast时需要格外小心。

因为dynamic_cast用来做向下类型转换,操作结果不一定总是成功的,在失败的情况下返回的指针值是零,如果继续使用会coredump.

8.为什么对不带有虚函数的类层次执行向下类型转换,使用static_cast比dynamic_cast好

因为,dynamic_cast会使用虚表里面的类型信息,所以不合理,就算没有虚表,额外的调用会导致效率比较低。

9.为什么头文件的规则:不要把分配存储单元的东西放到头文件 ?

分配存储单元必须指定一个名字,二头文件会被多次包括,如果没有使用排重宏,则会造成多次定义的错误,另一方面就算是有排重宏,由于多个单元可见,怎么协调和同步访问该块存储也是一个问题。

10.c语言的setjump和longjump在c++中有什么问题?
    a.保存点和返回点紧耦合
    b.不会调用析构函数。试想如果析构函数里面有关闭文件,关闭网络连接,释放内存等操作。

11.c++的异常机制有什么好处?

将业务逻辑代码和错误处理代码解耦,使代码结构清晰,易理解。

12.为什么类型转换构造函数在异常处理机制中不工作?

????,也许是因为异常处理器需要的是更原始,更真实,更具体的信息,如果发生转换这些信息很可能打折扣。

13. catch(...)存在的意义是什么?

释放资源本层,配合不带参数的throw可以将异常完整的传递到上一级,上一级可以继续获取异常信息进行处理。

14.如果被抛出的异常对象,析构函数会抛出异常,会发生什么?

本层处理器将不会处理该异常,如果没有上一层处理器,则terminate会被调用;如果有上一层处理器,上层可以 捕获这个异常,但是这种情况被认为是糟糕的设计或编码。

15.如果构造函数里边会抛出异常应该怎么做,因为析构函数不会被调用?
a.可以在构造函数里边进行异常捕获用于释放资源!
b.也可以将需要释放资源的指针封装成对象,然后将这些对象作为成员变量放在类里面,因为成员变量是对象,所以会在构造函数之前调用其构造函数,所以如果这个时候抛出了异常那么栈反解的时候就会把已经成功构造的给释放掉。

16.为什么最好不要直接从Exception派生自己的异常类。

因为Exception类没有接收字符串的构造函数,应该从其子类runtime_error或者logic_error来继承。

17.如果抛出的异常没有包含在异常规格说明,会发生什么?

unexpected会被调用。

18.对异常机制的使用规则

a.不要在中断处理程序中抛出异常,因为中断代码是独立的

b.简单程序不用异常

c.不要把异常用作流程控制。

d.能够处理的异常因尽早处理

e.避免在模板函数中进行异常规格说明,因为异常类型无法预测

f.如果异常只会被本类使用,应将其定义置于该类的名字空间中

g.从标准异常类派生,会比较友好

19.设计assert的意义是什么?

验证设计的正确性,导致断言失败的唯一原因是程序逻辑bug;

20.为什么要编写单元测试?

从代码层面上进程持续测试。

21.为什么要先编写单元测试?

帮助开发者在开始编写业务代码之前,做全名的考虑。

22.单元测试通过代表了什么?

理解了需求。

实现了需求。

23.为什么可以把标准输入输出,文件,内存,字符串都作为流操作?

因为他们都符合流操作的特征。

24.怎么利用字符串流实现数据类型转移?

template <class T> T stringTo(const string & str)
{
        T x;
        istringstream inStr(str);
        inStr>>x;
        return x;
}
template <class T> string toString(const T & t)
{
        ostringstream ostr;
        ostr<<t;
        return ostr.str();

}

25.怎么利用字符串流,实现浮点数拆分。

void splitDouble(const string & strDouble, int & pre, double & aft)
{
        istringstream iStrDoub(strDouble);
        iStrDoub>>pre>>aft;
}

26.输出流有哪些格式控制

27.为什么会有操纵算子?

因为操纵算子书写起来比格式设置函数简单,方便。

28.相应查操作算子有哪些?

29.为什么成员模板函数不能声明为虚函数。

因为,在编译器解析类的时候希望知道该类虚表的大小,如果允许成员模板虚函数,则必须提前知道所有该成员函数调用引起的实例化版本数量,这个需要扫描所有项目文件,非常不灵活,尤其在多项目文件的情况下。

30.为什么 模板的模板参数缺省值在所有地方必须出现?

。。。。。??

31.为什么通过单一模板参数声明的模板函数的多个函数参数,这些函数参数都由模板参数来定义,在调用时,即使给定的不同类型的参数有自动转换的路径,为什么还是要报错。

不符合模板函数声明,首先就找不到用来实例化的模板函数,根本走不到自动类型转换这一步。

32.类成员函数指针与普通函数指针的差别

a. 类成员函数指针是需要指向某类限定的名字空间中的函数,所以在声明时必须用类名来限定 void (className::*funcname)(paramlist)

b.因为类成员函数是需要通过类对象来调用以便设置this指针,所以在成员函数指针调用是也需要 objectName.*pfunc

c.成员函数指针,是指向某类名字空间下的具有指定参数列表和返回值的,所以在赋值时需要选取相应的类成员函数 pFunc=&className::funcname

33.什么是模板的半有序

取特殊程度最高的模板(和异常类型的匹配差不多),但是有时没有特化程度最高的,有多个并列的从而出现歧义,编译报错。

34.模板显示特化时,必须使用特化类型替换原来的模板参数类型,如果遇到const需要进行修正。

35.template<>说明所有参数都已经特化 , template<class T>说明T参数还没有特化。

36.为什么模板类只有被调用的成员函数才会实例化?

省事,省资源哇

37.函数模板不能特化只能重载。

38.由于模板类特化时要重新实现成员函数,所以特化的越多,代码工作量就越大。但是可以通过如下技巧减小代码量。

将需要特化的类型分为几个类别,然后为每个类别做一个完全特化,该类别下面的其他类型就从这个特化进行派生

例如:

template <class T>class Stack;

//完全特化

template<> class Stack<void *>

//为其他指针进行部分特化

template<class T>   class Stack<T *> : private Stack<void *>

39.但编译器遇到一个标识符时,必须确定哪些信息,为什么?

必须确定类型、作用域

知道类型才能确定长度和其他关联信息,知道作用域才能确定该标识符出现的位置是否正确。

40.特征类。

比如需要一个画人物肖像的类,这个类需要根据操作的对象,画出不同的器官特征,那么可以使用特征类技术。

假设画肖像的类的操作为画出眼睛,鼻子,嘴巴。

那么先定义 几个类 ,大眼睛,小眼睛,挺鼻子,塌鼻子,小嘴巴,大嘴巴

然后定义几个对象的特征类,在特征类中设置特征名称,美女特征类(眼睛特征类为大眼睛,鼻子特征类为挺鼻子,嘴巴特征类为小嘴巴),丑女特征类(眼睛特征类为小眼睛,鼻子特征类为塌鼻子,嘴巴特征类为小嘴巴)

最后操作类中首先根据模板类型所代表的特征类来设置特征类型,后续直接操作特征类型。

又如:

#include <iostream>

using namespace std;
//牛奶类
class Milk
{
        public:
                friend ostream & operator << (ostream & os,const Milk &)
                {
                        return os<<"Milk";
                }
};
//压缩牛奶类
class CondensedMilk
{
        public:
                friend ostream & operator << (ostream & os,const CondensedMilk &)
                {
                        return os<<"CondensedMilk";
                }
};

//蜂蜜类
class Honey
{
        friend ostream & operator<<(ostream & os,const Honey &)
        {
                return os<<"Honey";
        }
};

// 饼干类
class Cookies
{
        friend ostream & operator<<(ostream & os,const Cookies &)
        {
                return  os<<"Cookies";
        }
};

//定义几个访客类
//熊类
class Bear
{
        public:
                friend ostream & operator<<(ostream & os,const Bear&)
                {
                        return os<<"Big bear";
                }
};

//小孩类
class Boy
{
        public:
                friend ostream & operator << (ostream & os ,const Boy &)
                {
                        return os<<"Little boy";
                }
};

//主要traits模板(空模板可以持有所有普通类型)
template <class Guest> class GuestTraits;

//特化的traits类
template<> class GuestTraits<Bear>
{
        public:
                typedef CondensedMilk beverage_type;
                typedef Honey snack_type;
};

template<> class GuestTraits<Boy>
{
        public:
                typedef Milk beverage_type;
                typedef Cookies snack_type;
};

class MixedUpTraits
{
        public:
                typedef Milk beverage_type;
                typedef Honey snack_type;
};

//驱动类
template<class Guest,class traits=GuestTraits<Guest> >
class BearCorner
{
        Guest theGuest;
        typedef typename traits::beverage_type beverage_type;
        typedef typename traits::snack_type snack_type;
        beverage_type bev;
        snack_type   snack;
        public:
        BearCorner(const Guest & g):theGuest(g){}
        void entertain()
        {
                cout<<"Entertaining "<<theGuest
                        << " serving "<<bev
                        << " and "<<snack<<endl;
        }
};
int main(int argv,char ** args, char ** env)
{
        Boy boy;
        Bear bear;
        BearCorner<Boy> bc1(boy);
        bc1.entertain();
        BearCorner<Bear> bc2(bear);
        bc2.entertain();
        BearCorner<Boy,MixedUpTraits> bc3(boy);
        bc3.entertain();

return 0;

}

42.特征类组合策略,实现策略类,比如上面的画肖像,可以通过策略类转换为拍肖像等。

43.对象计数的高级实现

#include <iostream>

using namespace std;

template<class T>
class ObjCount
{
        static int cnt;
        public:
        ObjCount(){++cnt;}
        ObjCount(const ObjCount<T> & cnt){++cnt;}
        ~ObjCount(){--cnt;}
        static int getCount(){return cnt;}
};

template<class T> int ObjCount<T>::cnt=0;

class TestCnt1:public ObjCount<TestCnt1>{};//父类唯一

class TestCnt2:public ObjCount<TestCnt2>{};//父类唯一

int main(int argv,char ** args, char ** env)
{
        TestCnt1 t11,t12;
        TestCnt2 t21,t22;
        cout<<"TestCnt1::getCount="<<TestCnt1::getCount()<<endl;
        cout<<"TestCnt2::getCount="<<TestCnt2::getCount()<<endl;
        return 0;

}

关于bind1st/bind2nd

相关类一元函数类,二元函数类,binder2nd/binder1st

一般一元函数和二元函数继承自一元函数类,二元函数类,这中函数父类存在的意思是把参数类型名称以及返回类型名称统一化,以便外部接口统一访问。

bind2nd函数将一般的二元函数对象转换为binder2nd一元函数对象,binder2nd对象的调用重载会调用传入的二元函数对象。由于bind2nd接收的第一个参数是const限定的常量对象,所以传入的二元函数对象的operator()重装必须要用const限定。

时间: 2024-11-11 16:36:16

C++自问自答的相关文章

系统改版自问自答

系统改版,尤其是erp系统.资产管理等后台系统的改版,尤其要慎重,改版优化之前,先要做几个自问自答,帮助自己梳理好设计思路. 首先,为什么要改版 现存系统最大的问题是什么,为什么要改版? 具体可以通过访谈使用者.模拟使用场景.新人系统自学后访谈等方式,提炼各路人马在体验系统使用之后遇到的问题. 举个例子,假设你得到的原因有如下几个: 使用者人员流动大 严谨的专业词汇(toB产品的特性) 功能叠加无整体性 功能入口不明确 流程逻辑不易理解 缺乏一致性. 怎么改 根据系统改版原因,制定设计目标 由业

[python]自问自答:python -m参数? (转)

python -m xxx.py 作用是:把xxx.py文件当做模块启动但是我一直不明白当做模块启动到底有什么用.python xxx.py和python -m xxx.py有什么区别! 自问自答: python xxx.py python -m xxx.py 这是两种加载py文件的方式:1叫做直接运行2相当于import,叫做当做模块来启动 不同的加载py文件的方式,主要是影响——sys.path 这个属性.sys.path 就相当于liunx中的PATH. 下面来看一下sys.path >>

自问自答之VR遐想

先让我组织一下语言,作为表达能力超弱的战五渣来讲,归纳总结什么的最要命了. 我可以给你分析个1到N条出来,但是一般来讲没什么顺序,想到什么就说什么.而且我属于线性思维,有一个引子就可以按着话头一步步发散,但是特别容易舍本逐末.就是说,我能想到一个东西的用法,如果沿着该物品的思维线联想,可以想到其生产地.原料等等.但是,我为何会想到它呢?我可能就忘了我的初衷.比如现在就跑题了~ 为何要取名叫自问自答呢?这是因为我要先有个任务,然后才有完成任务的动力及目标.如果只是自由表述,那我能扯到外太空去.当然

自问自答-hadoop在安全模式下究竟干了什么见不得人的事

本来想自己从网上搜集整理的,但是发现吴超写的刚刚好,不多不少,所以直接转载(图片失效了,用自己的图片) http://www.superwu.cn/2013/08/23/548/ 在hadoop集群的时候,集群的运行会进入到安全模式(safeMode)下.在安全模式下运行一段时间后,自动退出. 那么,系统在安全模式下干什么了? 当集群启动的时候,会首先进入到安全模式.系统在安全模式下,会检查数据块的完整性.假设我们设置的副本数(即参数dfs.replication)是5,那么在dataNode上

python实用小技巧自问自答系列(一):查看类中函数文档doc的方法

问题:如何查看某个类的方法文档说明或者是函数的参数列表情况? 答: 方法一:直接在需要查询的方法后面加上".__doc__"即可以打印出该方法的文档说明(需要先导入该方法所属模块) 如: 方法二:在windows的命令行模式下还可以输入:"python -m pydoc 方法名"获取该方法的文档说明 如: 方法三:在ipython的命令行解释器模式下可以通过方法名+问号的方式来查看该方法的文档说明(需要先导入该方法所属模块)      如: 方法四:通过help函数

libgdx自问自答

1.使用gdx-steup.jar生成的desktop项目导入idea运行报如下错误,如何解决? 答:原因是assets目录默认是普通目录,idea编译项目时不会把普通目录下的内容输出到classpath下,导致找不到文件,设置为资源目录即可解决 原文地址:https://www.cnblogs.com/hihtml5/p/9690519.html

自问自答总结

1.现在做的这些项目,对于我们出工作后所做的有联系吗? 其实学完软件工程这门科目下来,我才明白原来我们现在做的就是在为未来打基础,所以我们现在需要更多的实际操作才行. 2.我不清楚我这样子的调试跟单元测试有区别吗? 其实这样的测试方法,并不是不行,而是没有单元测试那么全面,那样专业而已. 3.在这样的时代背景下,我们势必会在将来就业方面遭遇到许多沉重的压力,面对这样的一种压力,我们当下现在应该如何面对,怎么样处理? 每个人都会有压力的,不只是我自己,其他大家都一样,哪个行业都是一样,所以我们必须

自问自答

第一章:可以用单元测试来减少代码量,虽然没能完全解决,但是至少代码量少了. 第二章:单元测试是在没整合之前测试,整合之后再整体测试. 第三章:代码的杂乱会影响到我们对程序的修改和整理,也会影响以后的解决bug的速度.综合之下,别人的抄袭不如用户的体验重要. 第四章:大型公司的职业认证,对社会上的其他公司是有影响的 第五章:坚定自己的立场,相信有些人会了解你的. 第五章:模拟的,只有基本功能,没有细腻的,辅助的,完整的功能. 第六章:被误解,就需要我们去解释,还要用实际行动去证明. 第七章:道德优

我的安全测试面试_自问自答,不亦乐乎

不想做黑客的安全测试不是优秀的cybercop.怎么才能算是优秀的cybercop呢?那么就就必须学会或懂的黑客惯用一些手法与业内所流行的一些漏洞. 加QQ群:136611782 1.常见的几种攻击手段 CC攻击XSS攻击CSRF攻击SQL注入攻击TCP全连接攻击框架重定向攻击惯性思维逻辑攻击WEB Server多连接攻击 2.选择一个谈谈期原理 CSRF攻击 通过跨站点请求伪造盗取他人信息,常见方式有 http://javame.cnblogs.com/login?cas=web-cas&se

自问自答 学习系列(1):从图像分类,到损失函数,到神经网络

1.图像分类的挑战: 视角变化(Viewpoint variation):同一个物体,摄像机可以从多个角度来展现. 大小变化(Scale variation):物体可视的大小通常是会变化的(不仅是在图片中,在真实世界中大小也是变化的). 形变(Deformation):很多东西的形状并非一成不变,会有很大变化. 遮挡(Occlusion):目标物体可能被挡住.有时候只有物体的一小部分(可以小到几个像素)是可见的. 光照条件(Illumination conditions):在像素层面上,光照的影