望麓自卑—湖南大学最具潜力的校园传媒

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2838|回复: 5

我所接触的编程语言

[复制链接]
发表于 2007-7-20 00:38:47 | 显示全部楼层 |阅读模式
来源:BBS.TONGJI.NET
志于道,据于德,依于仁,游于艺    ——《论语•述而》

大巧在所不为,大智在所不虑。所志于天者,已其见象之可以期者矣;所志于地者,已其见宜之可以息者矣    ——《荀子•天论》

   



keyword:
C++, virtual inheritance, template;
Java, JVM, method table, thread, security;
COM, event, IDispatch, apartment, SCM, MTS, database;
.net, OO, MCMS





先从C++说起。C++学的时间最长,不仅周老师讲过,户sir也讲,侯捷也讲。。对象结构啊STL啊都讲烂了,实在是没什么新东西来写。说说虚拟继承吧。虚基类被作为一个单独的部分。写段程序就可明白虚拟继承的语意。编译器是简单方便的VC++6.0
1 虚拟继承使得不能通过父类的指针来访问子类,Base1虚拟继承了Root,
Root * pR = new Base1;报错:
Compiler Error C2243 'conversion type' conversion from 'class Base1 *' to 'class Root *' exists, but is inaccessible
2 如果改为Base1 * pR = new Base1;不报错,但是访问子类没有改写的虚函数会报错:no accessible path to public member declared in virtual base 'Root'
3 定义两个类:class Base1 : virtual Root, class Base2 : virtual Root, class Derived : public Base1, public Base2,如果Base1,Base2 中均改写了Root中某个虚函数,编译报错:ambiguous inheritance。只要把其中任一个虚拟继承改成public,就不报错。
4 将Base1的定义改为:class Base1 : public Root2, virtual Root
其中Root2也带虚函数,如果是一般的多重继承,如果VC++6是采用的N表结构,也就是多重继承中有几个带虚函数的父类就有几张虚函数表,那么Root的虚函数表应该追加到第一个带虚函数的父类的虚函数表中来作为整个继承类的虚函数表。但结果还是不能调用未改写的虚父类中的虚函数。
以上4点充分说明了虚基类被作为一个单独的部分。为什么第一条中不能调整指针?因为偏移值无法确定。为什么第三条中不能同时改写同一个虚基类中的虚函数?因为对应这个共用的虚基类只有一份虚函数表,不像多重继承,每个带虚函数的都有自己的表。
对于调整指针,设想两个类Base1,Base2都虚拟继承了Root,而某个类多重继承Base1 ,Base2,则这两个类的开始处与虚基类的偏移值肯定是不同的,只有一份虚基类被构造,所以根本没法调整。不含虚继承的多重继承中调整指针的例子:
如class Derived : public Base1, public Base2
则Base2 *pbase2 = new Derived; 会编译为:
Derived *temp = new Derived;
Base2 *pbase2 = temp ? temp + sizeof( Base1 ) : 0;
要让指针指向Base2子对象。为此发展出的thunk技术使得调用虚函数尤其析构函数时先将指针调整到合适位置。
说到继承,据说Sun公司的Mike Ball主持设计的C++编译器在多重继承时是一个虚函数表,不是N表。我想这对最终Java的method table的想法产生影响,Java对象也是一张表。本文下一部分将详细讲Java对象。

哀悼模板
模板给了我们不同于继承的重用机制,表达的语意是基于特征兼容的多态。特征兼容就是说,如果传入的模板参数T在内部被这样使用T[],那这个类必须有random访问算符才行。Stanley Lippman称赞模板是面向对象的高峰。确实,有些模板的巧妙用法让我感慨万分。《ATL Internels》上仿真动态绑定的例子:
template <typename T, typename Deriving>
class Array{
public:
...
bool operator<(const Array<T, Deriving>& rhs)
{ return static_cast<Deriving*>(this)->Compare(rhs) < 0 }
...
T m_rg[1024];
};
以后的派生类就可以这么写了:
class String : public Array<char, String>{
public:
int Compare(const Array<char, String>& rhs)
{ return strcmp(m_rg, rhs.m_rg);}
};
这样不用分配虚函数指针就能仿真实现多态了。看完这例子俺感慨道:不是缺少美,而是缺少创造--可惜这么强悍的东西要消失了。Java就没有真正的模板,只是种形式。C#最近才支持模板。为什么模板会消失?单根体系的出现使得不用模板就可解决问题。任何对象都可看作Object类的引用,类里增加个成员Object m_o,就可代替typename T,于是我们对模板说再见。消失的不仅仅是模板,.net的System.Collections包里不再需要链表了。。反正放的都是引用,又不是大对象。还有熟悉的iterator,它存在的意义就在于让内存布局不同的各种容器看起来都像数组。该消失的总会消失。就在此哀悼下C++吧,一个时代在慢慢地,悄悄地,结束,直到若干年后,没人会记起那些曾经辉煌的名字。
从Omale处得知C#的新版本支持模板时我很惊讶,这个世界太疯狂了,暑假前C#还不支持模板呢。这回是真正的模板,不是像Java中的伪模板,而且能加上限制,比如实现了A接口的类才能用到模板参数中。“基于特征兼容的多态”啊,“实现某接口”正是特征。为什么又需要模板了?单根体系带来向下转型的问题,而模板是参数化类型,避免了转型。

<a href=[[[SQ]]][[[www.wlzb.net/phpwind/read.php?tid=70770]]]></a>
发表于 2007-11-17 15:40:26 | 显示全部楼层
这不太懂,我现在学的是c语言,不太熟练
发表于 2007-11-20 13:17:47 | 显示全部楼层
貌似keywords里不都是语言的吧?
发表于 2007-11-23 00:41:15 | 显示全部楼层
肤淺,你连编程的门都没进呢.
发表于 2007-11-23 09:11:18 | 显示全部楼层
是啊
这是做作业
不是编程啊
发表于 2009-8-30 23:20:50 | 显示全部楼层
建议看看我某月前转的一篇 十年编程无师自通
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

每日推荐上一条 /1 下一条

小黑屋|手机版|湖南大学望麓自卑校园传媒 ( 湘ICP备14014987号 )

GMT+8, 2024-9-21 00:28 , Processed in 0.294662 second(s), 21 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表