被误解的C++——学习和使用

longshanks 2007-06-06 09:51:15
学习和使用
C++太复杂了。我猜想你一定是在计算机屏幕前不住地点头。其实我也在使劲的点头。没错,C++着实复杂,大概是迄今为止最复杂的语言。于是,便产生了一个推论:C++难学难用。
这句话也相当准确,但并非所有时候都这样。C++的学习和使用可以分为若干个层面,这些层面由简到繁,由易到难,分别适合不同层次的学习者和使用者。
先让我们来看看C++究竟有多复杂。我大致列了个清单,包括C++的主要语言特性。基本的一些特性,象变量、条件、选择等等,都掠去了,主要集中在体现C++复杂性的方面:
1. 指针。包括变量指针、函数指针等。可以计算。
2. 引用。包括变量的引用、函数的引用等。
3. 自由函数。
4. 类。包括具体类和抽象类。
5. 重载。包括函数重载和操作符重载。
6. 成员数据。包括static和非static的。
7. 成员函数。包括static和非static的。
8. 虚函数。包括对虚函数的override。
9. 继承。包括多继承、虚继承等。
10. 多态。包括动多态和静多态。
11. 类型转换。包括隐式的和显式的,以及臭名昭著的强制转换。
12. 模板。包括类模板和函数模板。
13. 模板特化。包括完全特化和部分特化。
14. 非类型模板参数。
15. 模板-模板参数。
我对照了C#的特性清单。C++比C#多的特性主要是:1、2、3、9的多继承、10的静多态、13、14、15。
而C#比C++多的特性主要有(这里没有考虑C++/CLI,C++/CLI补充了标准C++):
1. for each关键字。
2. as、is关键字。
3. seal关键字。
4. abstract关键字。
5. override/new关键字。
6. using关键字的一些补充用法。
7. implicit/explicit关键字。(C++有explicit关键字,但只用于构造函数)
8. interface关键字。
9. property。
10. delegate。
我们来分析一下。C++比C#所多的特性集中在编程技术方面,特别是编程模式,如由模板带来泛型编程和元编程机能。在OOP方面,C++走得更远,更彻底,主要表现在多继承和操作符重载方面。在传统的编程技术上,C++区分了对象和对象的引用(指针和引用)。而C#所有引用对象所持的都是引用。最后,C++拥有自由函数。
反过来再看C#,C#所多的都是些关键字。这些关键字都集中在OOP方面,并且都是以使编程技术易于理解为目的的。很多人(包括我在内)都希望C++也拥有C#的这些关键字(至少部分)。但与一般人的理解不同,C++标准委员会实际上是被编译器开发商所把持着,他们对引入关键字尤其神经过敏。没有办法,现实总是有缺憾的。
从这些方面可以看出,C++在编程机制上远远多于C#(Java的机制甚至更少)。对于新入行的人而言,一口气吞下这些内容,足以把他们撑死。相反,C#增加的关键字有助于初学者理解代码的含义。这些就是C#和Java比C++易于学习(易于理解)的真正原因。
但是,必须要强调的是,C#和Java中易于学习和理解的是代码,而不是这些代码背后的技术原理和背景。
我看到过的绝大多数C#代码都充满了重复代码和大量switch操作分派。如果这些程序员充分利用C#和Java的OOP机制,这些严重的代码冗余可以消除一半。(如果C#和Java具备C++那样的泛型编程能力,则另一半也可以消除。)这些程序员都是在没有充分理解语言机制和OOP技术的情况下编写软件,事倍功半。
这种情况在C++也有发生,但相对少些。这大概是因为C++足够复杂,使得学习者产生了“不彻底理解C++就学不会C++,就用不了C++”的想法。这种想法有利有弊,利在于促使学习者充分理解语言和语言背后的技术,而弊在于它吓跑了很多人。实际上,我们一会儿就会看到,C++可以同C#和Java一样,可以在不理解其中原理的情况下,仅仅按照既定规则编程。当然我们不希望这样,这是不好的做法。但鉴于现在业界
的浮躁心态,我们也就入乡随俗吧。
注意了!下面这句话是最关键的,最重要的,也是被长期忽略的:C++之所以复杂,是为了使用起来更简单。听不明白!自相矛盾!胡说!别急,且听我慢慢道来。
(限于篇幅,我这里只给出最后一部分案例代码,完整的案例在我的blog里:)
有三个容器,c1、c2、c3。容器的类型和元素的类型都未知。要求写一个算法框架,把c1里的元素同c2里的元素进行某种运算,结果放到c3里。
由于容器类型未知,必须使用所有容器公共的接口。所以,我写下了如下的C#代码:
public delegate void alg<T1, T2, R>(T1 v1, T2 v2, R r);
public static void Caculate_Contain<C1, T1, C2, T2, C3, T3>
(C1 c1, C2 c2, C3 c3, alg<T1, T2, T3> a )
where C1: IEnumerable<T1>
where C2 : IEnumerable<T2>
where C3 : IEnumerable<T3>
{
IEnumerator<T1> eai1 = c1.GetEnumerator();
IEnumerator<T2> eai2 = c2.GetEnumerator();
IEnumerator<T3> eai3 = c3.GetEnumerator();

while (eai1.MoveNext() && eai2.MoveNext() && eai3.MoveNext())
{
a(eai1.Current, eai2.Current,eai3.Current);
}
}
//使用
public static void CaculThem(int v1, int v2,int r) {
r=v1*v2;
}
Caculate_Contain(ai1, ai2, ai3, new alg<int, int, int>(CaculThem));
public static void CaculThem2(float v1, int v2,double r) {
r=v1*v2;
}
Caculate_Contain(af1, ai2, ad3, new alg<float, int, double>(CaculThem2));
我使用了一个委托,作为传递处理容器元素的算法的载体。使用时,用具体的算法创建委托的实例。但具体的算法CaculThem()必须同相应的容器元素类型一致。
下面轮到C++:
template<typename C1, typename C2, typename C3, typename Alg>
Caculate_Container(const C1& c1, const C2& c2, C3& c3, Alg a)
{
transform(c1.begin(), c1.end(), c2.begin(), c3.begin(), a);
}
//使用
template<typename T1, typename T2, typename R>
R mul_them(T1 v,T2 u) {
return v*u;
}
Caculate_Container(ai1, ai2, ai3, mul_them<int, int, int>);
Caculate_Container(af1, ad2, ad3, mul_them<float, double, double>);
如果容器元素有所变化,C#代码必须重写算法CaculThem()。但C++不需要,由于mul_them<>()本身是个函数模板,那么只需将这个函数模板用新的类型实例化一下即可。
C++的代码相对简单些,灵活性也更高些。但这还不是全部,C++还有一个最终极的解法,不需要循环,不需要创建模板算法,不需要写操作函数:
transform(c1.begin(), c1.end(), c2.begin(), c3.begin(), _1*_2);
...全文
17796 385 打赏 收藏 转发到动态 举报
写回复
用AI写文章
385 条回复
切换为时间正序
请发表友善的回复…
发表回复
huke3014 2011-11-14
  • 打赏
  • 举报
回复
热闹!`
return0x0 2008-04-12
  • 打赏
  • 举报
回复
这个楼好高啊~!

刚好占个386楼

争取冲向486、奔腾
zsxcn 2008-04-12
  • 打赏
  • 举报
回复
虽然我的东西不懂,但是还要顶
leozlin 2008-04-12
  • 打赏
  • 举报
回复
准备学习中,希望以后能学的好!为自己加油!
f22fbi 2008-04-10
  • 打赏
  • 举报
回复
mark学习
wuyecandi 2008-04-10
  • 打赏
  • 举报
回复
好东西
zmzbs123 2008-04-10
  • 打赏
  • 举报
回复
我也非常喜欢C++,哈哈
Who_know_me 2008-04-10
  • 打赏
  • 举报
回复
[Quote=引用 131 楼 zaxzab 的回复:]
学习 拼命赶上
[/Quote]
myullian 2008-04-10
  • 打赏
  • 举报
回复
好帖
gh880507 2008-04-10
  • 打赏
  • 举报
回复
强哦``!!!
好贴就要回``!
qqwaqq 2008-04-08
  • 打赏
  • 举报
回复
强贴,好贴,看了很多打击C++的贴后,终于见到了一个支持C++的了。
gaofen115 2008-04-01
  • 打赏
  • 举报
回复
so nice!楼主确实了解啊!小弟初来乍到,也在学习c++,我还是个大三学生,希望以后可以进入开发者的行列,和各位一起体验编程的乐趣!我建了个qq群46585285,希望大家有相同爱好的可以进来一起交流。
lily604 2008-04-01
  • 打赏
  • 举报
回复
c++这么多高级的功能不都是有库的支持吗,为什么没人给c#和java也编出这样的库来.个人觉得这些语言的难度平均是一样的,就像楼主说的使用boost库要达到很高的层次.到达的这个层次所付出的努力和学习c#或java的语法加上实现功能的算法应该是需要付出平均相同的努力的.主要就是编程思想的问题.比如opp.
add08 2008-04-01
  • 打赏
  • 举报
回复
顶一下
Soulic 2008-04-01
  • 打赏
  • 举报
回复
还是个菜鸟,学习了
lily604 2008-03-31
  • 打赏
  • 举报
回复
引用26楼
C++领域似乎总有一些人高高在上,当你觉得自己正在成长为一个语言大师(我想这个称号只存在于C++中)的时候,却发现自己其实连一个学徒都算不上。
.........................

我还不知道什么时候能体会到他所说的呢,努力......
WuBill 2008-03-31
  • 打赏
  • 举报
回复
就程序设计语言来说,远没有最好的,只有更好的,或者说只有更合适的。
能解决问题的都是好方法或是好语言。
VB、Delphi、C++、Java、C# 等语言各有所长,真的难分优劣。
开发人员应该根据客观条件,选择自己熟悉的语言,不要发誓忠于某某主义而自寻烦恼。
xqzl 2008-03-25
  • 打赏
  • 举报
回复
学过c++的,无论深浅,都喜欢发帖炫耀,故弄玄虚或一味贬低别人,这不是学习精神!
看codeproject上文章,比这里舒服!
bbsdkjdx 2008-02-28
  • 打赏
  • 举报
回复
通过http://blog.sina.com.cn/s/print_4ce1eaa7010008r4.html的报道,F22用的ADA,F35用的C++.
liveforme 2008-01-02
  • 打赏
  • 举报
回复
加载更多回复(365)
► 数据结构--序言数据结构--序言 在可视化化程序设计的今天,借助于集成开发环境可以很快地生成程序,程序设计不再是计算机专业人员的专利。很多人认为,只要掌握几种开发工具就可以成为编程高手,其实,这是一种误解。要想成为一个专业的开发人员,至少需要以下三个条件: 能够熟练地选择和设计各种数据结构和算法。 至少要能够熟练地掌握一门程序设计语言。 熟知所涉及的相关应用领域的知识。 其中,后两个条件比较容易实现,而第一个条件则需要花相当的时间和精力才能够达到,它是区分一个程序设计人员水平高低的一个重要标志,数据结构贯穿程序设计的始终,缺乏数据结构和算法的深厚功底,很难设计出高水平的具有专业水准的应用程序。曾经有一本经典计算机专业书籍叫做《数据结构+算法=程序》,也说明了数据结构和算法的重要性。 《数据结构》是计算机科学与工程的基础研究之一,掌握该领域的知识对于我们进一步进行高效率的计算机程序开发非常重要。无论在中国还是在美国,《数据结构》一直是大学的计算机专业重要的专业基础课。例如,在著名的美国的加州大学伯克利分校(著名的BSD Unix的发源地,很多Unix操作系统由它派生而来或带有它的痕迹——例如FreeBSD、Sun公司的Solaris、IBM的AIX),就用一个学期开设《数据结构和算法》课程(在这之前,用一个学期开设《C++程序设计》课程)。 现行的中学相关的计算机教程或者是关于怎样使用Windows操作系统及其工具、或者是有关办公软件的使用,或者是打字教程。计算机对他们始终有一种神秘感,也许是理论导向吧,因为不可能每个人将来都成为计算机专业人员。 作为一个中学生,在学完C/C++以后,关键的问题是怎样熟练地应用和巩固。本网站希望能够结合《数据结构》和相关的数、理、化知识来巩固C/C++。其实《数据结构》并不难。可以说,数据结构贯穿于我们的数学课程之中,只是思考问题方法的不同。在大学的《数据结构》教程中,很多生僻的词语、晦涩难懂的语句,连大学生就感到望而生畏。本网站将集合小学和中学的数学、物理、化学教材,深入浅出地讲解这门课程。希望不但能够对学习电脑有所帮助,更希望能够对数理化的学习起到一个促进作用。 在学习《数据结构》之前,要求学生有C/C++基础。可以这样说,C/C++是其他程序设计语言的基础。掌握了C/C++,学习其他语言就会易如反掌。例如,微软的MFC类库基于C++;ATL基于C++中的模板类;Java语言基于C++思想,其编程风格与C++差别很小;C++ Builder又是基于C++;Delphi中的有关对象的概念与C++中的对象几乎完全一致。C++相比其他语言具有与计算机硬件集合紧密、代码效率高,这是Java语言和其他高级语言所无法比拟的。这样,C/C++对于学习计算机系统结构有很大的好处。
第1篇 理解程序设计 第1章 基础知识 1.1 什么是编程 1.1.1 计算机如何工作 1.1.2 内存中的程序是哪里来的 1.1.3 可执行文件的制作 1.1.4 C语言的演化 1.2 怎样用C语言编程 1.2.1 学习C语言编程都需要什么 1.2.2 最简单的C语言程序的基本结构 1.2.3 Dev C++ 1.3 printf()函数初步 1.3.1 简单的一般用法 1.3.2 特殊的字符 1.4 C语言的“字母”和“单词” 1.4.1 C语言的字母 1.4 12C语言的“词” 小结 概念与术语 风格与习惯 常见错误 牛角尖 练习与自测 第2章 数据类型 2.1 什么是数据类型 2.1.1 “三个世界”理论 2.1.2 问题世界:“万物皆数” 2.1.3 代码世界:书写规则及含义 2.1.4 机器世界里的“机器数” 2.1.5 输出问题 2.1.6 计算2的1到10次幂 2.1.7 代码质量的改进 2.2 让程序记住计算结果——变量 2.2.1 计算机的记忆功能 2.2.2 在代码中实现“记忆 2.3 int类型——总结与补充 2.3.1 计算机表示负整数的几种方法 2.3.2 计算机码制和C语言的关系 2.3.3 暂时不必关心的一些细节 2.3.4 int类型值的范围 2.3.5 int类型常量在代码中的其他写法 2.3.6 Dev C++中int类型的机器数 2.4 对数据类型的进一步讨论 2.4.1 int数据类型的运算 2.4.2 数学公式与数据类型 2.4.3 数据类型——代码与编译器的约定 2.5 莫名其妙的“整型 2.5.1 unsignedint类型 2.5.2 long、short关键字描述的整数类型 2.5.3 没有常量的char类型 2.5.4 其他 2.6 浮点类型 2.6.1 double类型常量的代码书写规则 2.6.2 浮点类型数据存储模型 2.6.3 浮点类型的一些特性 2.6.4 浮点类型的运算 2.6.5 浮点类型的输出及其他 2.7 数据类型与算法 2.7.1 错误的数据类型 217.2 所谓算法 2.7.3 一个技巧 2.7.4 更高效率的写法 2.8 算法的特性 小结 概念与术语 风格与习惯 常见错误 牛角尖 练习与自测 第3章 运算符、表达式及语句 3.1 C的“动词”及“动词”的“宾语” 3.2 表达式——C语言的“词组 3.2.1 初等表达式 3.2.2 被误解的“() 3.2.3 带运算符的表达式 3.2.4 不像表达式的表达式 3.2.5 表达式:专业与副业 3.2.6 赋值运算符左侧的标识符称为左值 3.2.7 函数调用是表达式不是语句 3.3 谁是谁的谁 3.3.1 流行的谬误:优先级决定运算次序 3.3.2 “左结合性”是运算对象先与左面的运算符相结合吗 3.3.3 运算符、表达式小结 3.4 右值的类型转换 3.4.1 明确写出的显式转换——cast运算 3.4.2 cast运算的规则 3.4.3 赋值中的转换 3.4.4 1+1.0=? 3.4.5 算术转换:早已废弃的规则和依然有效的规则 3.5 语句的概念 3.5.1 关于语句的闲话 3.5.2 空语句有两种 3.5.3 表达式语句 3.5.4 顺序结构 3.5.5 复合语句 3.6 例题 3.6.1 简单的类型转换 3.6.2 最基础的算法——交换变量的值 3.6.3 编程不是列公式 3.7 算法和数据结构初窥 3.8 在程序运行时提供数据 小结 概念与术语 风格与习惯 常见错误 牛角尖 练习与自测 第4章 选择语句 4.1 关系运算 4.1.1 “<”的数学含义及代码含义 4.1.2 4种关系运算符 4.1.3 常见误区及与常识不符的结果 4.2 if语句 4.2.1 语法格式及含义 4.2.2 例题 4.2.3 ()内的表达式 4.2.4 ()后面的语句 4.3 判等运算 4.4 表达复杂的条件 4.5 if else语句 4.6 鸡肋——Bool类型(C99) 4.7 判断三角形种类 4.8 显得很有学问的运算符 4.9 大师如是说goto 4.10 给程序更多选项——Switch语句 4.10.1 switch语句的一种应用形式 4.10.2 switch语句中的break语句 4.11 程序开发的过程 小结 概念与术语 风格与习惯 常见错误 牛角尖 练习与自测 第5章 从循环到穷举 5.1 造句:当就 5.1.1 语法要素 5.1.2 猴子吃桃问题更简洁的写法 …… 第2篇 结构化程序设计与简单的数据结构 第6章 最复杂的去处符——“()” 第7章 作为类型说明符和去处符的“[]” 第8章 结构体、共用体与位运算 第9章 指针 第10章 字符串、字符数组及指向字符的指针 第3篇 复杂的数据结构、算法及其他话题 第11章 复杂的数据类型与算法 第12章 程序的输入与输出 第13章 程序组织与编译预处理 第14章 标准库简介 附录 参考文献

64,701

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧