代办
C++ 中static_cast、dynamic_cast、const_cast和reinterpret_cast总结
在标准C++中有四个类型转换符:static_cast、dynamic_cast、const_cast和reinterpret_cast;下面将对它们一一的进行总结。
1. static_cast
static_cast的转换格式:static_cast (expression)
将expression转换为type-id类型,主要用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。主要在以下几种场合中使用:
用于类层次结构中,基类和子类之间指针和引用的转换;
当进行上行转换,也就是把子类的指针或引用转换成父类表示,这种转换是安全的;
当进行下行转换,也就是把父类的指针或引用转换成子类表示,这种转换是不安全的,也需要程序员来保证;
用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等等,这种转换的安全性需要程序员来保证;
把void指针转换成目标类型的指针,是及其不安全的;
注:static_cast不能转换掉expression的const、volatile和__unaligned属性。
举个例子:
将int(4字节)显示转换成short(2字节),发现static_cast的作用就是将高位截断。
so,小结一下static_cast:
基本数据类型之间的转换,如把int转换成char,把int转换成enum
用于类层次结构中基类和子类之间指针或引用的转换。
进行上行转换(把子类的指针或引用转换成基类表示)是安全的;
进行下行转换(把基类指针或引用转换成子类指针或引用)时,由于没有动态类型检查,所以是不安全的。
把void指针转换成目标类型的指针(不安全!!)
2. dynamic_cast
dynamic_cast的转换格式:dynamic_cast (expression)
将expression转换为type-id类型,type-id必须是类的指针、类的引用或者是void *;如果type-id是指针类型,那么expression也必须是一个指针;如果type-id是一个引用,那么expression也必须是一个引用。
dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。在多态类型之间的转换主要使用dynamic_cast,因为类型提供了运行时信息。下面我将分别在以下的几种场合下进行dynamic_cast的使用总结:
a. 最简单的上行(xing)转换
比如B继承自A,B转换为A,进行上行转换时,是安全的,如下:
#include
using namespace std;
class A
{
// ......
};
class B : public A
{
// ......
};
int main()
{
B *pB = new B;
A *pA = dynamic_cast<A *>(pB); // Safe and will succeed
}
b. 多重继承之间的上行转换
C继承自B,B继承自A,这种多重继承的关系;但是,关系很明确,使用dynamic_cast进行转换时,也是很简单的:
class A
{
// ......
};
class B : public A
{
// ......
};
class C : public B
{
// ......
};
int main()
{
C *pC = new C;
B *pB = dynamic_cast<B *>(pC); // OK
A *pA = dynamic_cast<A *>(pC); // OK
}
而上述的转换,static_cast和dynamic_cast具有同样的效果。而这种上行转换,也被称为隐式转换;比如我们在定义变量时经常这么写:B *pB = new C;这和上面是一个道理的,只是多加了一个dynamic_cast转换符而已。
c. (这个真的是重点)如果expression是type-id的基类,使用dynamic_cast进行转换时,在运行时就会检查expression是否真正的指向一个type-id类型的对象,如果是,则能进行正确的转换,获得对应的值;否则返回NULL,如果是引用,则在运行时就会抛出异常;例如:
class B
{
virtual void f(){};
};
class D : public B
{
virtual void f(){};
};
void main()
{
B* pb = new D; // unclear but ok
B* pb2 = new B;
D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D
D* pd2 = dynamic_cast<D*>(pb2); // pb2 points to a B not a D, now pd2 is NULL
}
3. const_cast
常量指针被转化成非常量指针,并且仍然指向原来的对象;
常量引用被转换成非常量引用,并且仍然指向原来的对象;
const_cast的作用是用来改变表达式里面的常量性(const)或易变性(volatile)。
#include
using std::cout;
using std::endl;
int main(void)
{
const int b = 10;
//b = 11 报错,因为b是一个常量对象
int * pc = const_cast<int *>(&b);
*pc = 11;
cout << "*pc = " << *pc << endl;//b原来地址的数据现在可由*pc来改变,即解除const
cout << "b = " << b << endl; //b其实类似(编译器处理问题)#define b 10 不会变的
return 0;
}
常量指针被转化成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然指向原来的对象;常量对象被转换成非常量对象。
Voiatile和const类似。举如下一例:
class B{
public:
int m_iNum;
}
void foo(){
const B b1;
b1.m_iNum = 100; //comile error
B b2 = const_cast<B>(b1);
b2. m_iNum = 200; //fine
}
上面的代码编译时会报错,因为b1是一个常量对象,不能对它进行改变;使用const_cast把它转换成一个常量对象,就可以对它的数据成员任意改变。注意:b1和b2是两个不同的对象。
4. reinpreter_cast
用法:reinpreter_cast (expression)
说明:type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。它可以把一个指针转换成一个整数,也可以把一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的指针值)。
该运算符的用法比较多。
Vim使用技巧
d 加动作来进行删除(dd 删除整行);D 则相当于 d , 删 除 到 行 尾 。 c 加 动 作 来 进 行 修 改 ( c c 修 改 整 行 ) ; C 则 相 当 于 c ,删除到行尾。 c 加动作来进行修改(cc 修改整行);C 则相当于 c ,删除到行尾。c加动作来进行修改(cc修改整行);C则相当于c,删除到行尾然后进入插入模式。
s 相当于 cl,删除一个字符然后进入插入模式;S 相当于 cc,替换整行的内容。
i 在当前字符前面进入插入模式;I 则相当于 ^i,把光标移到行首非空白字符上然后进入插入模式。
a 在当前字符后面进入插入模式;A 相当于 $a,把光标移到行尾然后进入插入模式。
o 在当前行下方插入一个新行,然后在这行进入插入模式;O 在当前行上方插入一个新行,然后在这行进入插入模式。
r 替换光标下的字符;R 则进入替换模式,每次按键(直到 )替换一个字符。
u 撤销最近的一个修改动作;U 撤销当前行上的所有修改。
我们可以在会产生分割的命令(如 help 和 split)之前加上 vertical(缩写 vert),来进行竖直分割。对于最常见的竖直分割操作,我们则可以直接写成 :vsplit(缩写 :vs)
使用 vimdiff 或 gvimdiff 命令,后面跟两个文件名,我们就可以对这两个文件进行比较
10X工作法
任何事物都要经过两次创造:一次是在头脑中的创造,也就是智力上的或者第一次创造(Mental/First Creation),然后才是付诸实践,也就是实际的构建或第二次创造(Physical/Second Creation)。
概括地说,践行“以终为始”就是在做事之前,先考虑结果,根据结果来确定要做的事情。
扩大自己工作的上下文,别把自己局限在一个“程序员”的角色上。
双汇发展三大报表分析
第1步,准备好相关公司的年报。双汇过去5-10年的年报,双汇同行业前3名的公司过去5-10年的年报也要下载下来。
第2步,先看双汇发展最近期的年报。先从“合并资产负债表”开始看起。
第3步,把合并资产负债表各个科目看一遍,标记异常科目。先把资产负债表的每个科目快速看一遍,把占总资产比率大于3%且同比增长或下降大于30%的科目标记一下。
第4步,搜索异常科目,查明原因。
先来看一下货币资金变动的原因。
2018年货币资金金额比2017年减少了57.5%,我们可以看到双汇给的说明是股东分红以及买入银行结构性存款。我们来看下分红以及结构性存款的情况。
第5步,看总资产,判断公司实力及扩张能力。
以上是双汇发展、龙大肉食、华统股份3家公司2014-2018年的总资产。从总资产的规模来看,双汇发展大概是龙大肉食的10倍,华统股份的15倍。龙大肉食、华统股份和双汇发展明显不是一个量级的。从总资产的同比增幅来看,双汇发展有增有减,发展扩张能力较弱;龙大肉食增长速度很快10%-47%,尤其2018年成长速度非常快;华统股份增长速度也在加强。三家公司依然在扩张,龙大和华统扩张能力相对较强。
第6步,看资产负债率,判断公司的债务风险。
我们来看一下3家公司的资产负债率。
双汇2014-2018两年的资产负债率分别为: 25.57%,22.71%,29.43%,33.01%和37.36%。龙大2014-2018两年的资产负债率分别为:12.95%,15.77%19.65%,20.14%和40.09%。华统2015-2018两年的资产负债率分别为:46.64%,39.94,21.86%和33.85%。
3家公司的资产负债率都小于40%,偿债风险很小,龙大2018年超了一点,要持续关注是否会继续上升。双汇2017年的资产负债率有所上升,但是依然小于40%,没有问题。
第7步,看有息负债和货币资金,判断偿债风险。
有息负债总额=短期借款+一年内到期的非流动负债+长期借款+应付债券+长期应付款。
第8步,看“应收应付”和“预付预收”,判断公司的行业地位。
我们来看一下双汇发展的行业地位如何?
由上图知:双汇应收票据增加应收账款下降,应收款质量在提升,预付款降低话语权提升而应付款也在降低占用上游资金在减少被上游企业占用资金也减少,预收账款增加占用下游资金减少,可以看出总体而言双汇无偿占用其上游供应商和下游经销商的资金金额。这相当于双汇的上下游公司为双汇提供了大量的无息贷款。双汇具有“两头吃”的能力。双汇的行业地位很高,竞争力很强。;龙大肉食总体来看占用下游资金在增加,对下游话语权较强,而占用上游企业较少,话语权同样有所不足;华统股份总体来看占用下游资金在增加,对下游话语权较强,应付增加预付减少,其对上游话语权较强,其行业地位在提升。
我们可以计算出双汇应收账款与总资产的比率为0.58%,比率很低。这也说明双汇的经营风险很小。
我们来看一下龙大肉食的行业地位如何?
龙大肉食(应付票据+应付账款+预收款项)-(应收票据+应收账款+预付款项)龙大肉食的资金被其上游供应商和下游经销商占用了。这说明龙大肉食的行业地位较弱,竞争力较差。
龙大肉食不具有“两头吃”的能力,行业地位明显不如双汇发展。
我们来看一下华统股份的行业地位如何?
华统2018年(应付票据+应付账款+预收款项)-(应收票据+应收账款+预付款项),华统占用了其上游供应商和下游经销商的资金。这说明华统的行业地位较高,竞争力较强。值得注意的是2017年、2018年占用资金有所增加。这说明华统的竞争力在进一步增强。
华统具有“两头吃”的能力,但行业地位明显不如双汇。
通过行业地位分析,我们知道双汇发展稳居行业老大的地位,已经在行业中比较优秀的龙大肉食、华统和双汇相比还差很远。
第9步,看固定资产,判断公司的轻重。
双汇2014-2018年的(固定资产+在建工程+工程物资),与总资产的比率在50%左右。这个比率远大于40%。双汇为重资产型公司。双汇维持竞争力的成本相对比较高。
龙大2014-2018年的固定资产+在建工程+工程物资与总资产的比率:22%-27%。龙大属于轻资产型公司。维持竞争力的成本相对比较低。
华统2014-2018年的固定资产+在建工程+工程物资与总资产的比率为:47%-52%。华统为重资产型公司。维持竞争力的成本相对比较高。
第10步,看投资类资产,判断公司的专注程度。
我们很明显看出双汇和龙大肉食是非常专注于主业的,虽然华统股份投资类占比略大,但仍是小于10%,也是较为专注主业的好公司
下面我们再来看一下双汇发展本公司所持有的子公司的主业情况。
子公司数量较多,就不全部列出。我们发现双汇发展的子公司的主业全部都是和双汇发展主业相关的。
这说明双汇发展是一家非常专注于主业的公司。双汇发展在未来持续保持竞争优秀的概率较大。
第11步,把合并利润表和现金流量表各个科目看一遍,标记异常科目。
先把合并利润表中占总资产比率大于3%且增降幅度大于30%的异常科目标记出来。
我们可以看到双汇发展的合并利润表没有异常。
再把合并现金流量表中占总资产比率大于3%且增降幅度大于30%的异常科目标记出来。
第12步,搜索异常科目,查明原因。
投资支付的现金主要是双汇发展购买了银行结构性存款,分配股利支付的现金增加是由于双汇发展2018年年中分红,合并现金流量表的异常科目没有什么问题。
第13步,看营业收入,判断公司的行业地位及成长能力。
我们发现营业收入总量双汇远超龙大肉食和华统股份,其行业地位当之无疑的老大;双汇营业收入增长率双汇总体而言有下降趋势,而华统股份和龙大肉食的成长速度很快。三家公司的销售商品、提供劳务收到的现金/营业收入均超过100%,营业收入含金量高,行业地位较高。
双汇发展2014年-2018年的营业收入分别是456.96亿、446.97亿、518.22亿、504.47亿,487.67亿,金额很大,这说明双汇发展的实力很强。
双汇“销售商品、提供劳务收入收到的现金”2014-2018年的金额分别是497.97亿、487.97亿、560.36亿、545.96、531.61亿。
通过计算得出:2015-2018年营业收入同比增长率分别为-2.19%、15.94%、-2.65%、3.33%。营业收入增长率波动较大,但总体是增长的。这说明双汇的成长速度已经放缓,双汇处于成熟期。
通过计算得出:2014-2018年“销售商品、提供劳务收入收到的现金”与“营业收入”的比率分别为:108.98%、109.17%、108.13%、108.22%、109.01%。
可见双汇发展的营业收入含金量高,行业地位高。
我们再来看下同行业的龙大肉食和华统股份。
龙大肉食、华统股份的营业收入远远小于双汇发展,这说明双汇发展稳居行业第一名,是非常优秀的公司。
第14步,看毛利率,判断公司产品的竞争力。
毛利率看五年的数据,2014-2018年双汇发展的毛利率分别为:19.93%、20.77%、18.11%、18.91%、21.42%,毛利率总体稳定,但是均低于40%,说明双汇的产品竞争力不强。
我们再看一下同行业的龙大肉食、华统股份的毛利率。
龙大肉食,毛利率在7%-9%。
华统股份毛利率为4.9%-8%。
龙大、华统的毛利率远低于双汇。这说明双汇的产品在行业内还是有很强的竞争力的。只是双汇所处的行业不是一个好行业。
第15步,看费用率,判断公司成本管控能力。
2014-2018年双汇发展的费用率为从43.82%下降至37.24%,说明双汇发展的成本管控能力强。
我们再来看一下龙大肉食,费用率/毛利率的比率在50%以上,远大于40%,说明龙大肉食的成本管控能力很一般。
我们再来看一下华统股份,费用率/毛利率的比率在50%以上,远大于40%,华统股份的成本管控能力很一般。
和同行相比,双汇有更强的成本管控能力。
第16步,看主营利润,判断公司的盈利能力及利润质量。
通过计算得出,2014-2018年双汇发展的主营利润分别为:49.29亿、53.59亿、55.92亿、56.08亿、62.11亿。
主营利润率分别为10.78%、11.99%、10.79%、11.12%、12.74%,主营利润率比较稳定,但都小于15%。主营利润率小于15%的公司,对成本、费用的变化比较敏感。
主营利润/利润总额的比率分别为91.72%、94.43%、95.40%、97.39%、98.09%,均>80%,双汇发展的利润质量还是非常高的。利润质量高,利润的稳定性和持续性就较好。
相比之下,龙大肉食和华统股份的利润质量略逊色,尤其是华统股份,其利润质量较差,稳定性一般,持续性也较为一般。
第17步,看净利润,判断公司的经营成果及含金量。
双汇2014-2018年净利润分别为:42.15亿、44.16亿、45.62亿、45.11亿、50.76亿。
经过计算得出:2014-2018年双汇发展的净利润现金比率分别为111.78%、130.56%、121.58%、125.26%、102.33%,都>100%;
说明双汇发展不但净利润金额大,而且含金量很高,其净利润中都是真金白银。
龙大肉食的净利润现金比率很不稳定,2018年还出现了负值,华统股份净利润现金比率很高,含金量高。
第18步,看归母净利润,判断公司自有资本的获利能力。
双汇发展的连续5年净资产收益率在27%以上,大于15%,说明双汇发展自有资本的盈利能力很强。而其他两家都未及15%,其盈利能力一般。
第19步,看经营活动产生的现金流量净额,判断公司的造血能力。
双汇发展2014-2018年的经营活动产生的现金流量净额分别为:47.12亿、57、66亿、55.46亿、56.5亿、54.95亿,金额大,说明双汇发展的造血能力很强。
2014-2018年“固定资产折旧+无形资产摊销+借款利息+现金股利”的总和分别为:41.17亿、41.38亿、82.76亿、50.91亿、78.11亿。(“分配股利、利润或偿付利息支付的现金”这个科目就是现金股利+借款利息)
2014-2018年,经营活动产生的现金流量净额与“固定资产折旧+无形资产摊销+借款利息+现金股利”的差额分别为5.95亿、16.28亿、-27.3亿、55.94亿和-26.16亿。2016年、2018年为负,是因为双汇发展超额分红所致。根据2017年的情况,正常分红情况下双汇发展可以通过自身的造血能力满足扩大再生产的需求。
三家企业对比来看华统股份的现金流似乎不错,但同样在分红方面就较少了。
第20步,看“购买固定资产、无形资产和其他长期资产支付的现金”,判断公司未来的成长能力。
双汇发展连续 5 年“购买固定资产、无形资产和其他长期资产支付的现金” 与“经营活动产生的现金流量净额”的比率分别是:52.82%、39.12%、16.15%、9.32%、9.92%,这说明双汇发展一直处于稳步成长中,2017-2018年成长速度放缓。“处置固定资产、无形资产和其他长期资产收回的现金净额”与“购买固定资产、无形资产和其他长期 资产支付的现金”的比率分别为0.25%、1.01%、1.63%、15.03%、12.8%,2014-2016年,公司在快速成长,2017-2018年双汇的成长放缓,未来成长性可能一般。
而龙大肉食和华统股份两家不稳定且有超100%的年份,成长速度很快,但过于激进。
我们具体看下双汇的状况
我们发现处置或报废的固定资产为1.12亿,所以“处置固定资产、无形资产和其他长期资产收回的现金净额”中主要是清理陈旧的固定资产,设备进行更新换代,没什么问题。
另外对比一下2015年2016年”购建固定资产、无形资产和其他长期资产支付的现金“科目,金额别是225.6亿、89.58亿,2017年和2018年分别是5.27亿和5.15亿,金额大幅减少,说明双汇近两年没有进行大规模扩张,业务处于平稳状态。
第21步,看分红判断公司的品质。
双汇2014-2018年的分红比率为:77.35%,96.9%、157.3%、84%、97.35%。可见双汇发展还是非常慷慨的。这种分红水平的公司,财务造假的可能非常小。但是由于双汇分红比率大幅高于70%,我们知道这种高分红的情况是很难持续的。未来双汇发展的分红比率应该会回归70%左右的水平。
相比之下龙大肉食和华统股份就显得对投资者不够慷慨。
第22步,看三大活动现金流量净额的组合类型,选出最佳类型的公司。
双汇发展2014-2018年的类型是“正正负”和“正负负”型。属于优秀公司的类型。
龙大肉食在2018年出现了“负负正”类型,即经营亏钱的状态下还在增加投资,还在不断地融资以维持企业运行。
华统股份2014-2018年的类型是“正正负”和“正负负”型。属于优秀公司的类型。
第23步,看“现金及现金等价物的净增加额”,判断公司的稳定性。
双汇发展2014-2018年的“现金及现金等价物的净增加额”分别为:-9.14亿、-4.83亿、5.81亿、27.68亿、-34.12亿。2014、2015、2018年的金额为负,
“现金及现金等价物净增加额+分红金额”分别为22.77 亿、26.42亿、76.75亿、67.27 亿、31.88亿; 在加回分红后,现金净增额大于0,公司在不断积累更多的财富,可以持续性发展。
龙大肉食和华统股份都有加完分红仍小于0的情况,状况一般。