老生常谈C++, 又是充满BUG的一天

        很久没写过文章了,今天来谈一谈,这么多年自己使用C++的一点看法与理解!!包括解答一下,为什么这个东西,学起来这么累,学了这么多年始终云里雾里。这可能大部分人停留在的地方原因。C++的书是越看越多,反而觉得越来越肤浅。尽头在哪里?路又在哪里?陷入了无限的迷茫。

        C++11之后,诞生了很多的新特性。让很多人反感,不愿意接受。觉得多此一举,不用这些我也一样的使用啊!NO!并不是这样。新特性,为什么要叫做新特性。新特性就是为了能够足够的标准化,明确化,使代码看起来不是那么的一坨,以及让你调试起来不至于在三天才解决一个BUG!能更快的解决问题。当然,这可能会使你的代码变得的臃肿一点。怎么写个代码,还带那么多前缀,后缀的。如果这样理解,就彻底错了。按照欧美那边的习惯与标准,添加足够的注释,会使得代码的更加的具体与明确,使得你调试起来,可以尽快的定位问题,看起来一目了然。比如,我们在C++里面会做各种类型的强制转换与隐式转换,某些时候,在你不知道的情况下,C++帮你做了隐式转换,你也没意识到,或者你做了强制转换,但,并没有标记ta。过了段时间不记得了。所以这里就存在了问题。你会发现,代码运行一切正常,就是打不到正确的位置上没得到你想要的结果,总是存在偏差。这个时候,你就百思不得其解了;于是,你不得费劲心力的开始逐行调试代码,看每一个数值的输出结果,不断比对。最后才发现,原来是在转换的时候,数值缺失了,或者某个对象引用错误了。 Boom!你炸了!这么一个小小的错误,却让你翻了如此大的车。甚至,你都差点开始怀疑写了这么多年代码,都是狗p了。  
        所以, 在我们遇到这样的问题,如果能在转换的时候在代码中填写了某个(***_cast)或者在进行对象转换的时候用到了某个(***_cast)。这个时候,我们的代码就会变得更加的明确与具体一点了。所以,一旦出现了问题。这里会发生什么?我们会Ctrl+Shit+F全局搜索某个(***cast),很快的定位问题,排查并解除问题,继续下一项工作。所以我们来简单说一下这几个(cast)吧!。

分别是:const_cast、static_cast、dynamic_cast、reinterpret_cast

const_cast:表示 我要去掉const属性。

static_cast:表示静态数据之间的转换,比如 int 到float 的转换,也可以用在类对象直接的隐式转换。更加具体与明确了我在这里进行了转换。

dynamic_cast:所以有静态,必须要有动态了。c++标准会真是做了太多的事情了。主要用在类多态虚函数情况下的转换,dynamic_cast 更多的是一种防御性的措施,用判断我是否能进行类与类之间的相互转换。

reinterpret_cast:这个就不要乱用了。解释一下主要用于进行指针之间的强制类型转换,可以将任何类型的指针转换为任何其他类型的指针,但是可能会导致不可预期的行为。

这里,我解释一下,指针之间的相互操作,访问内存,是一直存在的一种操作,即便不用ta我也可以直接转换,访问另一块内存,详见古老的C语言。到了c++保留了这种操作。使用

'reinterpret_cast` 好比,C++显示的告诉了你“兄弟,你在这里强制转换了类型指针” 如果出错了,可以尽快的定位这里。

        当然,这里并不是让你滥用,滥用的代码,写啥都不会明确。ta会有那么一点的性能上的损耗,因为ta需要一种运行时“动态检查(RTTI)”的机制,好的,这差不多就是四种cast 的一些简单使用注意事项了。

       所以,这一个小问题,就引发雪崩式的灾难。让我们不断的回想每一行代码会出问题的地方。然鹅,这只是C++的冰山一角。你以为你撞的只是小小冰块,然鹅,下面却是一座深不见底的冰山。 这也是很多人 无法驾驭这门古老而又强大语言的原因之一。so, C++标准会正在努力的解决这些事情,并不断的推出新的版本,使得C++更加的强悍与易用性。全世界使用C++的人,也在努力解决这些事情。    解决什么问题?  解决内存问题与各种缓存不命中的问题,所以,你的职业生涯在使用C++,那必将逃不过这样的问题,而且会是你每天都要面对的。 接受折磨吧!老弟儿!    但,不可否认C++ 的强悍,执行与效力性,是所有语言都无法比拟的。 曾有人问我: “哥,我大学四年学完了,所以C++书籍,数据结构 什么水平?” 我只想说:“冰山,你只撞到了指甲盖那么点的大小”。     

       还有一些其它的关键字,我们也一并说了吧!

有:auto、 using 、explicit、=delete、=default、final、virtual、constexpr、noexcept inline

拿几个我个人常用的吧!确实帮助我们解决问题,优化代码的。

1. `auto` - 自动类型推断,用于简化变量声明和类型转换。这个尽量少用,尽管ta是auto的,还是少用,会增加我们代码的阅读性。

2. `using` - 这个对应我们长年使用的typedef, using 能更好的帮助 我们优化代码。

3. `explicit` - 显示转换 ,表示禁止隐式的类型转换,必须显示转换。

4. `=delete` 表示删除此函数。

5. `=default` 表示设置为默认构造函数。

代码段:

class A
{
public:
	A() = default;  //默认构造函数

	explicit A(const A&) = default; //显示的拷贝构造函数

	A& operator= (const A& a) = default; //拷贝赋值
	
	explicit A(A&&) = default; //显示的移动构造函数
	
	A& operator=(const A&&) =delete; //删除的移动赋值 

	~A(); // 析构函数

private:

};

4 `override` - 表示必须重写的基类函数。
5. `final` - ,表示禁止类的进一步继承或函数的重写。

所以,这里两个算是多态的双胞胎兄弟。“final”其实很不常用,毕竟多态就是为了实现。

f9bf4551c87d461188edace09ac9dc5a.png

6.  constexpr、这个就理解为const 的强化版吧!编译时就要知道运算结果,更加高效的解决了const在内存效率上的问题
7. `noexcept` - 表示此函数不会抛出异常,没有异常,会发生什么。编译器会显著的优化代码,提高运行速度。如果你非要处理异常,编译器会调用一堆七哩八啦的事务,进行栈展开,最终terminate GG掉。显示你不会处理异常!

 好了,这差不多就算是我们在写C++常遇到一些新特性关键字了。当然,还有一部分没拎出来。还有一些比较基础的我就不说了。暂时就先到这里吧!如果你想更加深入的探讨C++,这算是我的一点拙见,请保持持续的视野,开拓性与扩展性,并不断的发掘。不要自卑与怀疑人生。

     

   

(备注:我说的是C++11之后的事情,以及新特性的一些故事与看法。太古老的我们就不谈了。)

   我们文章主题虽然再说如何处理,解决BUG,但是,还隐藏了两个,那就是 通透,具体与明确化 使你的代码变得更加的具体,一目了然。所以,如果你想成为更高一级的程序员,开始着,尝试做出改变吧!

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yewencc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值