更多课程 选择中心

C/C++培训
达内IT学院

400-111-8989

C 与 C++ 的真正区别在哪里?

  • 发布:C++培训
  • 来源:问答库
  • 时间:2020-06-05 17:14

除了面向对象与面向过程这个回答之外,C 与 C++ 的真正区别在哪里?这几年不管是社团实习工作面试都有被问到这个问题。但是「面向对象以及面向过程」这个回答似乎都不是最好或者最完善的答案。希望能从语言的语言特性,使用场景,设计哲学等方面得到完整解释。

关于C/C++,我最想吐槽的就是:void*是万恶之首。因为它有指鹿为马的强大威力,所以可能让人无法自拔。任何void*最初的类型都需要靠程序员人肉掌控,代码写多了,就总有出错的时候,后果就是轻则程序崩溃,重则是指鹿为马无限久还不知道鹿已是马,面目全非了。

void*在C里面无法被取代,但是在C++里面基本上是可以不用的。首先,C++类的继承关系,使得子类和父类的指针在转换时不需要用void*。子类指针到父类指针无需人肉转换,父类指针到子类指针用dynamic_cast,这个是运行时安全的。其次,C++模板使得在通用算法上的void*也变得没有必要了。

在我们现在的代码里面,只有我老大写的一个200行左右的mempool里面用了void*,实际上这里面的void*也是可以用模板改掉的,但是一来是因为它已经很稳定无需增加新功能了,二来是因为我老大现在已经不写代码了,这个文件是仅存的有他署名的代码,所以我一直没改掉。

总之呢,C++比C最大的改进之一就是增加了很多类型安全的功能,在编译(或者运行时如dynamic_cast)时避免了指鹿为马事件的发生,程序运行起来更加的安全。

从类型安全的角度来说,我觉得不存在任何人肉类型转换的代码就是好代码,我现在就是尽量做到这一点。这里的人肉转换包括C语言风格的转换,也包括C++风格的***_cast。如果需要任何类型转换,就说明存在设计的缺陷。当然了,如果实在有避免不了的时候,建议把含有类型转换的代码隔离起来,放在单独的模块或文件中,对其作充分的代码review、写完善的单元测试。

形如short s = 5; int i = 8888888; s = i;这种narrow conversioin也是极其危险的,但是现代C++编译器都会对这种代码给出警告甚至错误。

内存泄露与越界是C/C++世界两大灾难。关于内存泄露,因为服务器可以用mempool,除了不需要delete以外还可以避免内存碎片提高运行速度,所以对于如何应付内存泄露我没有特别的心得。但是对于如何应对内存越界,有一些小经验。

例如memcpy函数

void * memcpy ( void * destination, const void * source, size_t num );

就是容易发生越界的一个经典函数,刚开始做后台的几年里面因为这个函数出现的内存问题次数不少,但是后来发现可以用C++的方法来改造它。

总结了一下实际memcpy函数使用主要有两种场景,一是对于结构体的拷贝,二是对于char类型的数组的拷贝。先说结构体的拷贝,对于Struct A {....};A a, b;如果要把b的内容拷贝到a,有两种方法:

memcpy(&a, &b, sizeof(a));或者:a = b;前面一种方法容易出错,改成后面一种。(a=b这种赋值拷贝的方法在C里面也是可以的,不能算是C++的改进,感谢miloyip指正)。

memcpy函数需要使用的第二种场景,是将结构体拷贝到一个buffer中,类似这样:

char buff[N]; memcpy(buff, &a, sizeof(a));

这个当然也不是类型安全的,容易出问题,用C++的方法可以这样改造:

template<size_t N, class A>void memcpy_safe(char (&arr)[N], const A* p){ static_assert(sizeof(A) <= N, "error blabla"); ::memcpy(arr, p, sizeof(A));}

然后调用memcpy_safe(buff, &a)就安全了。

当然这里有个问题,就是拷贝的目标地址buff,必须声明为char buff[N]的形式,不能直接用char buff = new char[N]的形式,需要动态创建buffer的时候可以将buff封装在结构体里面,如:struct buffer_type { ...; size_t length; char buff[MAX_LEN]; }; 然后buffer_type* p = new buffer_type; memcpy_safe(p->buff, &a); 我们后台代码中类似用法已经全部改掉了。同理把snprintf之类的函数也全部用C++的方法封一遍,常见的内存问题都解决了。这些年我带的项目运营事故越来越少了,慢慢地在老大心中形成了一种口碑。

C与C++"真正"的区别在哪里?因为大家都已经回答了很多了,我提供一个比较感性的答案。在我看来,我觉得C就像一片充满荆棘的沼泽地,各种坑无处不在;而C++呢,就像是一座高山,C有的坑它都有,而且增加了无数新坑,但它还是竭尽所能地提供了一条安全上山的道路,想要冒险的时候可以去路边的丛林里玩耍,需要在工程中应用的时候又可以回到路上,工作娱乐两不误。

当然了,C与C++都有一个共同的与众不同的能力,就是让你能够把你的优选代码封装成祖传程序库,传给下一代。

一些区别:

C: 编写C代码,写出来的是C代码。

C++:编写C++代码,写出来的是还是C代码。

C:运行时内存错误。

C++:看起来像是运行时内存错误。

C:编译器警告你。

C++:编译器警告它自己。

C:1天学会,1年掌握。

C++:1年学会,-1年掌握。

C:Goto有害。

C++:C++可以无害。

C:入门语言。

C++:出门语言。

C:面向过程。

C++:面向C++。

C:一切皆指针。

C++:一切皆编译器。

C:烂代码能轻易编过,也能轻易调过。

C++:烂代码不能轻易编过,也不能轻易调过。

C:说精通的可能精通。

C++:说精通的肯定不精通。

当你还在担心能否就业时,达内学员提前被企业录取;当你转辗于各大招聘会时,达内学员收到了高薪offer;当你在各大招聘网站投递简历时,达内学员中有人一毕业进入五百强名企。所以选择很重要。找C++培训班,选达内就对了。

版权声明:转载文章来自公开网络,版权归作者本人所有,推送文章除非无法确认,我们都会注明作者和来源。如果出处有误或侵犯到原作者权益,请与我们联系删除或授权事宜。

预约申请免费试听课

填写下面表单即可预约申请免费试听!怕钱不够?可就业挣钱后再付学费! 怕学不会?助教全程陪读,随时解惑!担心就业?一地学习,可全国推荐就业!

上一篇:什么时候用C而不用C++?
下一篇:C语言是怎么来的?

空指针到底是什么意思?

a[i] = i++ 到底对不对?

C++培训哪家好?全方位对比机构

C/C++中的必须熟记的基础知识

  • 扫码领取资料

    回复关键字:视频资料

    免费领取 达内课程视频学习资料

  • 搜索抖音号

    搜索抖音号:1821685962

    免费领取达内课程视频学习资料

Copyright © 2021 Tedu.cn All Rights Reserved 京ICP备08000853号-56 京公网安备 11010802029508号 达内时代科技集团有限公司 版权所有

选择城市和中心
黑龙江省

吉林省

河北省

湖南省

贵州省

云南省

广西省

海南省