所有由yl发布的文章

C++之static_cast

cplusplus.com中的解释:

“static_cast can perform conversions between pointers to related classes, not only upcasts (from pointer-to-derived to pointer-to-base), but also downcasts (from pointer-to-base to pointer-to-derived). No checks are performed during runtime to guarantee that the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe. On the other side, it does not incur the overhead of the type-safety checks of dynamic_cast.

1
2
3
4
classBase {};classDerived:publicBase {};
Base * a =newBase;
Derived * b =static_cast<Derived*>(a);

This would be valid code, although b would point to an incomplete object of the class and could lead to runtime errors if dereferenced.
Therefore, static_cast is able to perform with pointers to classes not only the conversions allowed implicitly, but also their opposite conversions.
static_cast is also able to perform all conversions allowed implicitly (not only those with pointers to classes), and is also able to perform the opposite of these. It can:

  • Convert from void* to any pointer type. In this case, it guarantees that if the void* value was obtained by converting from that same pointer type, the resulting pointer value is the same.
  • Convert integers, floating-point values and enum types to enum types.

Additionally, static_cast can also perform the following:

  • Explicitly call a single-argument constructor or a conversion operator.
  • Convert to rvalue references.
  • Convert enum class values into integers or floating-point values.
  • Convert any type to void, evaluating and discarding the value.

从上面的内容来看,static_cast的功能还是很多的。记录重要的几点:

1. 相当于C语言的强制类型转换。如把int转成size_t:static_cast<size_t> i_value

2. 做基类的下行转换时,不安全,建议用dynamic_cast.

3. 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。

4. 把空指针转换成目标类型的空指针。

5. 把任何类型的表达式转换成void类型。

6. static_cast不能转换掉expression的const、volatile、或者__unaligned属性

C++之reinterpret_cast

在cplusplus.com中的解释如下:

reinterpret_cast converts any pointer type to any other pointer type, even of unrelated classes. The operation result is a simple binary copy of the value from one pointer to the other. All pointer conversions are allowed: neither the content pointed nor the pointer type itself is checked.

It can also cast pointers to or from integer types. The format in which this integer value represents a pointer is platform-specific. The only guarantee is that a pointer cast to an integer type large enough to fully contain it (such as intptr_t), is guaranteed to be able to be cast back to a valid pointer.

The conversions that can be performed by reinterpret_cast but not by static_cast are low-level operations based on reinterpreting the binary representations of the types, which on most cases results in code which is system-specific, and thus non-portable.

大意是说主要用于指针类型的转换,以及指针与足够大的整数类型之间的转换;从整数类型(包括枚举类型)到指针类型,无视大小。比特位不变。安全性由程序员自己保证

判断大小端及字节交换

之前写过一篇“如何判断机器的CPU是大端还是小端?http://www.orangespeech.com/?p=89”的blog, 现在更新一下开源代码中的简洁实现:

int IsLittleEndian() {
int check = 1;
  return (*reinterpret_cast<char*>(&check) != 0);
}

C的实现如下:

 #define BIG_ENDIAN      0
 #define LITTLE_ENDIAN   1

  int little_endian(void)
  {
      short int w = 0x0001;
      char *byte = (char *) &w;
      return(byte[0] ? LITTLE_ENDIAN : BIG_ENDIAN);
  }

顺带给出字节交换的代码,同样厉害!

#define SWAP8(a) { \
  int t = ((char*)&a)[0]; ((char*)&a)[0]=((char*)&a)[7]; ((char*)&a)[7]=t;\
      t = ((char*)&a)[1]; ((char*)&a)[1]=((char*)&a)[6]; ((char*)&a)[6]=t;\
      t = ((char*)&a)[2]; ((char*)&a)[2]=((char*)&a)[5]; ((char*)&a)[5]=t;\
      t = ((char*)&a)[3]; ((char*)&a)[3]=((char*)&a)[4]; ((char*)&a)[4]=t;}
#define SWAP4(a) { \
  int t = ((char*)&a)[0]; ((char*)&a)[0]=((char*)&a)[3]; ((char*)&a)[3]=t;\
      t = ((char*)&a)[1]; ((char*)&a)[1]=((char*)&a)[2]; ((char*)&a)[2]=t;}
#define SWAP2(a) { \
  int t = ((char*)&a)[0]; ((char*)&a)[0]=((char*)&a)[1]; ((char*)&a)[1]=t;}

纯虚类与dynamic_cast

今天看到一段代码,用dynamic_cast将每个vector的成员cast到基类。但是,如果基类是一个纯虚类,似乎没有这个必要。以下是我的实验:

#include <iostream>
#include <vector>

using namespace std;

class Father{
        public:
                virtual void get()=0;
};
class Son: public Father{
        public:
                void get(){ cout<<"Son"<<endl;}
};

class Daughter: public Father{
        public:
                void get() {cout<<"Doughter"<<endl;}
};

int main(){

        vector<Father *> a;

        Son s1;
        a.push_back(&s1);
        Daughter d1;
        a.push_back(&d1);

        for(size_t i=0;i<a.size();i++){
            //Father *ts = dynamic_cast<Father *>(a[i]);
            //ts->get();
            a[i]->get();//可以获得与上两行一样的结果
        }
        return 0;
}

最近读到《资治通鉴》上一段话,觉得说得太好了,摘抄下来,供今后慢品。

 “夫信者,人君之大宝也。国保于民,民保于信;非信无以使民,非民无以保国。是故古之王者不欺四海,霸者不欺四邻,善为国者不欺其民,善为家者不欺其亲。不善者反之,欺其邻国,欺其百姓,甚者欺其兄弟,欺其父子。上不信下,下不信上,上下离心,以至于败。所利不能药其所伤,所获不能补其所亡,岂不哀哉!”

回忆

若干年后,我们将如何回忆这样一场变故?从个人的角度,谈一谈对于许多事情的看法。
对于生命,多一份珍惜与敬畏。科技发达的今天,一个病毒足以摧毁整个医疗系统,生命变得如此脆弱。如果不好好珍惜,逝去有时很轻易。如果不多一份敬畏,生命的休止符常常来得悄无声息。
对于善与美,多一份感动与感激。那些战斗在一线的人,他们可以是出于职责,可以是出于号召,但不能不被他们感动。安宁的日子里,都不过是平凡角色的扮演者;在这些特殊的日子,他们站在了第一线,为我们筑起防线,保卫了我们的健康与安宁。
对于丑与恶,多了一份不耻与严厉。无论身居何位,无论影响大小,图一己之私利,于公众利益而不顾,更有甚者,趁火打劫,为非做歹,常叹良知何在!
对于未来,多了一份期待与信心。经过这一场变故,我们才会发现,安居乐业的日子不容易,才是真真切切的幸福。我们也会发现那些需要改进的地方,只有做得更好,更完善,才能抵御风浪,才能有实实在在的幸福!

三省

看得越多,想得越多。眼界开阔,却不能忽视了自己的内心。内心足够强大,方能走得更远。每个人的成长都是从0不断完善的过程,或无意识,或迫于无奈,但主动最好。
“世界上最难攀登的山其实是自己”,没有人了解“你”这个个体,现实所有的事物都是有章可循,唯有“自己”,无人可解。
“三省”真是必要,每天都审视,都总结,做到吸收教训,总结经验,只为做最好的自己。
再见,2018!
欢迎,2019! 

吃饭时吃饭,睡觉时睡觉

这是一句颇有禅意的话,第一次是从林清玄的书看来,具体的书名不记得,时间过了很久,对这一句话,印象还是最深。

现在的生活中总有许多放不下的东西,比如手机。先来说说吃饭。餐前要约饭,开始之前要拍照,发朋友圈;饭至最兴处,要发红包,抢红包;酒足饭饱,话题无趣,开始摆弄手机;散席回家,要叫车,醉酒了叫代驾…“无手机,不吃饭”。很享受在老家陪爸妈吃饭的时间。到点了,我妈叫一句“吃饭”,有人拿筷子,有人拿碗,有人抬桌。家常菜,也没拍照的必要。发红包就算了,我爸微信还没玩溜,我妈的手机是诺基亚的黑白屏;没人提喝酒的事,要喝自己倒,喝不醉,醉了就在家里休息。手机瞬间只是个物件,有时不是想起看时间,在家,手机还真没什么用。

再来说说睡觉,现在不到十二点是绝没勇气睡着的,即使躺下,也是翻来覆去,不熬到点绝不敢睡去。新上映的电影还没看,发的朋友图有没有人给我点赞,还有几页书没看,明天要不要跟客户开个会…烦恼太多,放不下,所以睡不着。人说三十岁之前睡不醒,三十岁之后睡不着。三十岁之前我不相信,三十岁之后深有体会。

放下,放下!

好好吃饭,好好睡觉!

“你想要改变,就得学会在乎”

在我们的人生,总会定个各种各样的目标,或大或小,或远或近。有了目标,就得改变,就得花时间,就得练习,不断重塑自己。

什么时候我们才会停下脚步,随时间褪去激情?年少无知,年轻豪情,年老却又体力不支,最尴尬的莫过于中年。

三十而立说中年,是不是太早?若不早省,岁月一划,怕是连回望的时间都没有。上有老,下有小,生活平静,比上不足,比下有余。够不着的,警戒自己,别痴心妄想。

幸福只是平淡,还是一切归于“不在乎”?不在乎那些人来人往,潮起潮落,仿佛看尽世间真知,看透人生灼见。

有没有某个时间,会想曾经立下的誓言,许下的承诺?是否缺了勇气回味!真不在乎,就会无感,改变何来?

观《叶问2》有感

昨晚电影台播放《叶问2》,打开电视的时候,已经放到叶问单挑香港各大武行了。

小朋友问我,这是什么,我说是“武术”。她好像不明就里,倒也看得津津有味。

对电影本身的武术和表演没什么兴趣,电影中的一些片断,倒是让我好好思索了人性和尊严两个词。

咱们华人团体历来都是“严于律己,宽人待人”,明明在社会上已被洋人当成奴才了,还自己要分个什么宗,什么派。彼此还要分个高低贵戝。在洋人面前点头哈腰的,对自己人却是撇着腿,呷着茶。别说当时不被洋人看不起,即使是今天自己人看来,也是有种“骨子里戝”的悲愤。

叶问最后打败了西洋拳王,说了一句“人的地位虽然有高低之分,但是人格,不应该有贵贱之别。”这算是给电影做了一个总结,作为胜利者,是应该得到所有人的掌声。但是,人格之于地位,如礼仪之于财富。《史记-货殖列传》中就有“仓廪实而知礼节,衣食足而知荣辱“,我们可以批评西洋拳王的盛气凌人,但同时,我们自己是不是应该团结、有自尊呢?