任何语言都有一个由浅入深的积累过程必须靠大量的实际开发来真正理解这个语言的特性,才能真正发挥这个语言的优势,完成各种类型的任务。
C++是一开始就把全部复杂性摆在程序员面前,必须对其基本特性有深入的理解才能写出可用的代码,但是一旦理解了,也就那么回事。
java、c#、python等语言将多数复杂性封装起来,以方便多数人的方式呈现给大家,
使的开发效率大大提高,代价是一定的开销和在特定领域的限制。但是也保留了提高性能和完成特定任务的途径。
一个C++的高手并不比其他语言的高手高,精通c++的人要精通其他语言同样需要大量的学习和实践,才能高效率的编写优质代码。
事实上,现在的C++真的有些误入歧途,兼容历史代码的包袱固然是重要原因,但是设计者的理念才是最根本的。
C++的语言及库的实现存在两个根本的冲突,为了解决这两个冲突导致的问题和陷阱不断的打补丁,导致程序员需要掌握越来越多的“高级特性”。
有些人把这些高级特性当作C++强大和高深的证明,殊不知这正是C++设计缺陷的表现。
C++的第一个冲突是编程范式。c++号称支持多种编程范式,首先是传统的smalltalk和java式的编程,提供了在指针基础上的继承虚拟和多态,代表是QT;其次是以模板为基础的泛型和函数式编程,代表是STL和boost;
问题是,这两种范式不完全相容,开发者需要一开始就想好要采用哪种范式(如基于iterator的算法无法用于基于虚函数接口的容器)。这还好,最麻烦的是要用的到第三方代码的时候,需要开发者做大量的工作在不同库之间调和。
我把前者成为运行时多态,后者称为编译时多态,编译时多态的将多态开销移至编译时,调高了运行时效率,但同样也牺牲了编译器进行静态类型检查的优势,提高了调试成本。我不认为这是合算的。
c++的另一个冲突是面向对象编程和传值方式的冲突。对象是一个实体,自己管理自己的内容,而传值则需要直接处理内存布局,为了解决这个冲突,c++引入了各种拷贝和移动构造函数,然后为了提高效率又引入右值引用和移动语义...
为什么不直接用指针呢,哦,如果用指针,就没法直接用运算符重载,对容器算法也要做额外的工作...
当你花了不少时间构建好了自己的库,可以得心应手的开发的时候,才发现原来自己在实现其他语言编译器实现的功能,而且引入的开销基本也相当于该语言和c++之间的性能差距,所以,悲剧的是,C++的性能优势也没了。
总的来说,在出发点和目的地之间,C++提供了一个庞大的网络,里面有最近的路径,也有非常远的路径,需要程序员自己去发现,这需要数年的实践才能做到。而java、c#等语言之提供了一条或为数不多的对多数人满意的路径,程序员不用选择,照着走就行了,这只要数月的训练就能达到。
所以我对初学者的建议是,如果自己可以选择,在可能的情况下(考虑任务、第三方库)使用java、c#等更高级的语言,性能的差距没你想的那么大,但是开发效率可以提高十倍。
反过来,如果我要招聘c++程序员,我宁愿花3倍的价钱找有多年实际开发经验的,也不要免费的初学者。
C++是一开始就把全部复杂性摆在程序员面前,必须对其基本特性有深入的理解才能写出可用的代码,但是一旦理解了,也就那么回事。
java、c#、python等语言将多数复杂性封装起来,以方便多数人的方式呈现给大家,
使的开发效率大大提高,代价是一定的开销和在特定领域的限制。但是也保留了提高性能和完成特定任务的途径。
一个C++的高手并不比其他语言的高手高,精通c++的人要精通其他语言同样需要大量的学习和实践,才能高效率的编写优质代码。
事实上,现在的C++真的有些误入歧途,兼容历史代码的包袱固然是重要原因,但是设计者的理念才是最根本的。
C++的语言及库的实现存在两个根本的冲突,为了解决这两个冲突导致的问题和陷阱不断的打补丁,导致程序员需要掌握越来越多的“高级特性”。
有些人把这些高级特性当作C++强大和高深的证明,殊不知这正是C++设计缺陷的表现。
C++的第一个冲突是编程范式。c++号称支持多种编程范式,首先是传统的smalltalk和java式的编程,提供了在指针基础上的继承虚拟和多态,代表是QT;其次是以模板为基础的泛型和函数式编程,代表是STL和boost;
问题是,这两种范式不完全相容,开发者需要一开始就想好要采用哪种范式(如基于iterator的算法无法用于基于虚函数接口的容器)。这还好,最麻烦的是要用的到第三方代码的时候,需要开发者做大量的工作在不同库之间调和。
我把前者成为运行时多态,后者称为编译时多态,编译时多态的将多态开销移至编译时,调高了运行时效率,但同样也牺牲了编译器进行静态类型检查的优势,提高了调试成本。我不认为这是合算的。
c++的另一个冲突是面向对象编程和传值方式的冲突。对象是一个实体,自己管理自己的内容,而传值则需要直接处理内存布局,为了解决这个冲突,c++引入了各种拷贝和移动构造函数,然后为了提高效率又引入右值引用和移动语义...
为什么不直接用指针呢,哦,如果用指针,就没法直接用运算符重载,对容器算法也要做额外的工作...
当你花了不少时间构建好了自己的库,可以得心应手的开发的时候,才发现原来自己在实现其他语言编译器实现的功能,而且引入的开销基本也相当于该语言和c++之间的性能差距,所以,悲剧的是,C++的性能优势也没了。
总的来说,在出发点和目的地之间,C++提供了一个庞大的网络,里面有最近的路径,也有非常远的路径,需要程序员自己去发现,这需要数年的实践才能做到。而java、c#等语言之提供了一条或为数不多的对多数人满意的路径,程序员不用选择,照着走就行了,这只要数月的训练就能达到。
所以我对初学者的建议是,如果自己可以选择,在可能的情况下(考虑任务、第三方库)使用java、c#等更高级的语言,性能的差距没你想的那么大,但是开发效率可以提高十倍。
反过来,如果我要招聘c++程序员,我宁愿花3倍的价钱找有多年实际开发经验的,也不要免费的初学者。