首页 >>  正文

c++能做什么项目

来源:baiyundou.net   日期:2024-07-01

【CSDN 编者按】一直以来,C 和 C++ 都是非常优秀的编程语言。不过,两种语言虽名称有些相似,但应用场景存在巨大的不同。对于 C 语言而言,其主要被用于操作系统、容器、物联网、数据库等领域的开发,而 C++ 则是开发桌面软件、图形处理、游戏、网站的最佳工具。在本文中,作者原以为 C++ 在开发基础设施时会更胜一筹,然而经过与 C 语言的尝试对比,发现事实并非如此。

原文链接:https://250bpm.com/blog:4/?continueFlag=c778b3c9525d12a012a35269d830ebcc

声明:本文为 CSDN 翻译,转载需注明来源。

作者 | Martin Sústrik 译者 | 弯月 责编 | 屠敏

出品 | CSDN(ID:CSDNnews)

以下为翻译正文:

首先声明,在整个职业生涯中,我一直在使用C++,而且在做大多数项目时,C++仍然是我的首选语言。

因此,在开始构建个人项目ZeroMQ(可伸缩的分布式或并发应用程序设计的高性能异步消息库)时,我也选用了C++,主要原因如下:

C++包含一些数据结构和算法库。如果使用C语言,我将不得不依赖第三方库,或者自己动手编写基本算法。

C++会强制我在编程风格上保持一些基本的统一性。例如,this参数不允许使用几种不同的机制将指针传递给正在处理的对象,而这个问题在C项目中很常见。同样,不可以明确将成员变量标记为私有,此外还有C++的一些其他特征。

使用C语言实现虚函数非常复杂,会导致理解和管理代码的难度加剧。不过,严格来说,这个问题其实是上一个问题的一个子集,但我觉得有必要单独指出。

最后,每个人都喜欢在代码的末尾自动调用析构函数。

然而,事到如今,我不得不承认C++是一个糟糕的选择。下面,我来解释一下原因。

首先,我的个人项目ZeroMQ是一个持续运行的基础设施,永远不应该出故障,永远不应该表现出未定义的行为。因此,错误处理至关重要,必须做到明确且严格。

然而,C++的异常处理并不能满足我的需求。如果程序不会出错,那么选择C++没有任何问题,只需将main函数包装在try/catch中,集中在一个地方处理所有错误。

如果你的目标是保证不会出现未定义的行为,那么C++的异常处理就会变成一场噩梦。由于C++解耦了异常的发生与处理,因此错误处理非常容易,但也造成了你几乎不可能保证程序永远不会运行未定义的行为。

在C语言中,错误的产生和处理是紧密结合的,在同一块源代码中。因此,在出错时很容易理解发生了什么:

int rc = fx ();if (rc != 0)handle_error ();

而在C++中,你只能抛出错误,却不清楚究竟发生了什么:

int rc = fx ();if (rc != 0)throw std::exception ();

问题在于,你并不清楚在哪里处理异常。处理错误的代码在同一个函数中会更加方便理解,尽管不太方便阅读:

try {...int rc = fx ();if (rc != 0)throw std::exception ("Error!");...catch (std::exception &e) {handle_exception ();}

然而,我们来考虑同一个函数抛出两个不同的错误,结果会怎么样:

class exception1 {};class exception2 {};try {...if (condition1)throw my_exception1 ();...if (condition2)throw my_exception2 ();...}catch (my_exception1 &e) {handle_exception1 ();}catch (my_exception2 &e) {handle_exception2 ();}

以下是等效的C代码:

...if (condition1)handle_exception1 ();...if (condition2)handle_exception2 ();...

相较之下,C语言更加方便阅读,而且编译器也会生成更高效的代码。

然而,C++的问题还不仅限于此。考虑某个函数会引发异常,但不会处理异常的情况。在这种情况下,错误的处理可以放到任何地方,具体取决于从哪里调用该函数。

针对不同的情况,采用不同的方式处理异常?这种方法听起来似乎很有道理,但很快就会变成一场噩梦。

在修复某个Bug时,你会发现许多其他地方也有相同的Bug,因为它们都复制了同一段错误处理代码。每当添加一个函数调用,就有可能增加一个新异常,如果调用函数的代码没有妥善处理该异常,就意味着增加了一个新Bug。

如果你还想坚持“没有未定义的行为”原则,就不得不引入新异常,以便区分不同的故障模式。但是,添加新异常就意味着,它会上升到不同的地方。你必须在所有地方添加相应的异常处理,否则就会出现未定义的行为。

看到这里,你可能想说:这就是异常的正确用法啊?

然而问题在于,异常只是一个工具,目的是用更系统的方式管理呈现指数增长的错误处理代码,但它并不能解决根本的问题。甚至可以说,异常有可能导致情况恶化,因为你不仅需要编写新的异常类型,还需要针对新类型编写异常处理代码。

考虑到上述问题,我决定使用C++,但不使用异常。如今我的这个项目就是这样实现的。

不幸的是,问题并没有就此止步……

考虑一下,如果对象的初始化失败,会发生什么?构造函数没有返回值,因此只能通过抛出异常来报告失败。但是,我决定不使用异常。所以,我们必须像下面这样处理:

class foo{public:foo ();int init ();...};

在创建实例时,会调用构造函数(这个函数不会失败),然后调用init函数(这个函数可能会失败)。

与C语言相比,C++代码更复杂:

struct foo{...};int foo_init (struct foo *self);

然而,C++代码真正的问题在于,如果开发人员在构造函数中编写一些代码,会发生什么?

在这种情况下,会出现一个特殊的新对象状态。由于对象已构造,但尚未调用init函数,因此是“半初始化”状态。我们应该修改对象(特别是析构函数)来处理这个新状态。这意味着,给每个方法添加新条件。

有人可能想说,这还不是因为你人为地添加了不使用异常的限制?!如果构造函数中抛出异常,C++运行时会正确地清理对象,不会出现“半初始化”状态。

话虽如此,然而问题在于,如果使用异常,如上所述,就必须处理所有与异常相关的复杂性。对于一个需要在遇到故障时表现出优秀的健壮性的基础设施组件来说,这不是一个合理的选择。

此外,即使初始化没有问题,对象的销毁也绝对会遇到问题。你不能在析构函数中抛出异常。这可不是我强加的人为限制,而是因为如果在进程中调用析构函数,或者恢复栈时恰好抛出异常,就会导致整个进程崩溃。

因此,如果销毁可能失败,你就需要两个单独的函数来处理它:

class foo{public:...int term ();~foo ();};

这就遇到了与初始化相同的问题:一个“半终止”状态,我们必须以某种方式处理,向各个成员函数添加新条件。

class foo{public:foo () : state (semi_initialised){...}int init (){if (state != semi_initialised)handle_state_error ();...state = intitialised;}int term (){if (state != initialised)handle_state_error ();...state = semi_terminated;}~foo (){if (state != semi_terminated)handle_state_error ();...}int bar (){if (state != initialised)handle_state_error ();...}};

与之相比,C语言的代码如下。其中只有两种状态。未初始化对象/内存,我们无需担心上述问题,而且结构可以包含任意数据。而且只要对象进入已初始化的状态,就可以正常工作。因此,对象中不需要状态机:

struct foo{...};int foo_init (){...}int foo_term (){...}int foo_bar (){...}

考虑一下,如果在上述代码中添加继承,会发生什么。C++允许将基类初始化为派生类构造函数的一部分。如果抛出异常,就会破坏已成功初始化的对象:

class foo : public bar{public:foo () : bar () {}...};

然而,一旦引入单独的init函数,状态的数量就会开始增长。除了未初始化、半初始化、初始化和半终止状态之外,你还会遇到这些状态的组合。你可以想象一个基类已完全初始化、但派生类半初始化的对象。

对于这样的对象,几乎不可能确保其行为不出问题。对象的半初始化和半终止部分有很多不同的组合,并且鉴于它们只在非常罕见的情况下才会引发故障,因此大多数相关代码可能未经测试就进入了生产。

综上所述,我认为,如果你的需求是不允许出现未定义的行为,则不适合面向对象的编程。这个问题不仅限于C++,任何具有构造函数和析构函数的面向对象语言都不适合。

因此,更适合面向对象语言的项目是:对开发速度有要求、但对“不存在未定义的行为”没有太高要求。

这个问题没有灵丹妙药。系统编程选择C语言更为合适。

","force_purephv":"0","gnid":"92b7ffcb55294c67a","img_data":[{"flag":2,"img":[{"desc":"","height":"80","s_url":"https://p0.ssl.img.360kuai.com/t0186957a1ca5352752_1.gif","title":"","url":"https://p0.ssl.img.360kuai.com/t0186957a1ca5352752.gif","width":"640"}]}],"original":0,"pat":"art_src_1,fts0,sts0","powerby":"hbase","pub_time":1661324889000,"pure":"","rawurl":"http://zm.news.so.com/c9821dc354e500629137570d8de4f6f9","redirect":0,"rptid":"51c3c8ef2a5835b6","s":"t","src":"CSDN","tag":[],"title":"我为什么放弃 C++,选择 C 语言编写个人项目?

巩帘万1987学习C C++编程语言之后,能做的最简单的项目有哪些? -
冉宽匡18362477843 ______ 黑屏白字的学生成绩管理系统、通讯录管理系统、图书馆管理系统…………不要以为一两百行,最起码700行代码以上.

巩帘万1987目前C++开发都做些什么啊? -
冉宽匡18362477843 ______ 我找工作的时候也犹豫过的,考虑到底是要从事c++或者java.我学的是java,但是面试的时候是c++.....所以,现在我做的是c++.提供一些自己的看法,希望能对你有帮助.c++与java相比,(1)内存方面.c++需要程序员跟内存打交道...

巩帘万1987C++为主体的项目一般是什么样的项目?具体说说 -
冉宽匡18362477843 ______ 其实一般是后台程序. 请注意VC++跟纯的C跟C++的差别. 一般C,C++都做后台程序,虽然,C++也可以用来做前台的界面,

巩帘万1987适合初学者的C++项目 -
冉宽匡18362477843 ______ 我给吧 是我们老师给我们编的一套上机实验 挺好的. 案例1:Score.一个学生成绩处理程序.包括自顶向下的设计方法,问题分析图(PAD),结构体数组,冒泡排序,计算名次,使用函数,甚至包括使用自定义头文件等知识. 案例2:...

巩帘万1987不知道现在的C++语言主要被用来做什么开发 -
冉宽匡18362477843 ______ c,c++主要用来开发系统软件等效率要求较高的软件,比如操作系统(当然最主要的核心部分是用效率更高的汇编写的)比如SQL server等,再比如Photoshop,还有几乎所有大型游戏全是C/C++开发的,由于现在的硬件发展很快,对效率的要求没有以前严格了,所以c++好像被边缘化了,但是你只要看看,几乎所有的系统API源码都是C/C++,就应该知道c/c++还是鼎梁柱 c/c++不太容易上手,不适合界面开发,以至于初学者以为它很弱

巩帘万1987C++可以写什么样的程序? -
冉宽匡18362477843 ______ 那你知道为什么是底层吗,不是任何语言都能做底层的,底层肯定是运行要快,要稳定,要有高效率.就像数学一样很多科目都需要他做基础,你觉得他重要不.就像地基一样,房子地基不好楼再好也不行.C++语言照样可以写出JAVA能写出的一切程序.看你怎么写而已

巩帘万1987C++现在主要用于什么项目的开发,C++的前景怎么样;比如找工作什么的好找吗? -
冉宽匡18362477843 ______ 现在C++可以说是使用率最高的编程语言了,所以前景大大的好!C++一般用于工程上面的开发,还有可以写一些与硬件的接口,这位些都是很吃香的!所以只要楼主把C++学好,就不要怕找不到工作,哈哈!

巩帘万1987求助学c++可以做什么 -
冉宽匡18362477843 ______ C++更加擅长系统软件和在乎效率的大型游戏一般的应用软件现在很少用C++开发

巩帘万1987用C++可以做什么作为毕业设计用的小项目? -
冉宽匡18362477843 ______ vc毕业设计,如:某小企业进销存管理系统,socket局域网通讯等都可以,毕业设计看两方面,一是选题技术含量,二是工作量,两者互补.以上两个选题涉及不到太多界面的东西,当然自己丰富下界面更好,用到数据库,多线程足矣.类似的选题还有很多.

巩帘万1987我想问学好里C语言或C++可以做什么? -
冉宽匡18362477843 ______ c语言是爸爸,c++是儿子.这样就可以去做技术了.可以去开发软件了,学到一定程度就明白了,刚刚开始都是这样的迷茫的,编程到底是编写什么啊?到底能做什么呢?学懂了就知道答案了.但

(编辑:自媒体)
关于我们 | 客户服务 | 服务条款 | 联系我们 | 免责声明 | 网站地图 @ 白云都 2024