KeyFC欢迎致辞,点击播放
资源、介绍、历史、Q群等新人必读
KeyFC 社区总索引
如果你找到这个笔记本,请把它邮寄给我们的回忆
KeyFC 漂流瓶传递活动 Since 2011
 

[M] Prelude to K.O. (4)

[ 17040 查看 / 45 回复 ]

回复:[M] Prelude to K.O. (4)

感觉这目前这4章讲述的越来越乱了.其实只要几张图及少量说明就能了解总体框架了.
我一直认为"simple is best".这个系统现在看起来还是有些复杂,我们经常遇到越复杂的东西越容易出问题,模块开发者也会感到困惑和误用.一个模块可以简洁地只导出一个函数,返回接口指针即可,此时模块就可以做初始化,不必再调用attach.
当然我还没能全面了解,不清楚一些复杂功能的必要性.
COM就是为了跨编程语言而没有内在地使用智能指针,而多出了AddRef/Release的接口.当然C++的广泛应用使得大多数架构不必做到跨编程语言.
想必CAS也是用C++实现的吧.如果能提供一些sample代码,就能更清楚地了解运行的流程.
本主题由 管理员 深海蓝空 于 2007/5/17 13:35:24 执行 设置精华/取消 操作
分享 转发
TOP

回复:[M] Prelude to K.O. (4)

设计的简单灵活就可以把基本接口确定下来,这样每个模块返回的接口指针都不会有不兼容问题,可以用接口中的一个方法返回版本或是signature,不会有"dll hell"的问题.如果扩展接口,像COM那样提供QueryInterface就解决了.
我不知道Object Pascal的虚函数表是否和C++的虚函数表在二进制上兼容.
但我认为Object Pascal的使用范围非常狭窄,可移植能力也很有限.
要想发展,就必须考虑支持C++编写的模块.

另外,我没说CAS核心是很乱的,我上面说的只是这4次讲述是越来越乱的,
也许您的时间比较宝贵,或者急于奉献自己的宝贵思想.没有很好地整理.这个我可以理解.
最后编辑dwing 最后编辑于 2007-05-17 09:30:45
TOP

回复:[M] Prelude to K.O. (4)

其实选择语言是很重要的,没有虚函数/抽象函数的支持,COM和CAS都很难实现.
虽然Object Pascal支持抽象函数,但语言本身貌似还没真正标准化.
其使用者比C++少得多,编译器比C++少得多,优化效果也差些,写核心也用不上delphi的众多GUI控件.
所以我很怀疑用Object Pascal实现的原因.难道只是因为习惯问题?
TOP

回复:[M] Prelude to K.O. (4)

我还是认为: 如果设计足够简单并保留一定灵活性和扩展性,就可以把interface确定下来.
现在看起来比较好的pascal编译器只有borland在做,而C++,至少MS,GNU,Intel的编译器都非常完善.
我上面对Pascal的一部分认识应该成为共识了,现在仍用pascal/delphi的看起来只有习惯问题和RAD这两个原因了.如果还有哪些优势,请不吝赐教.
java的运行效率是致命弱点,跨平台能力也不是广告说的那样(我体验过).
.NET在这两方面比java更差,可能好处只是MS的支持和比较好的开发环境.

忽然想起Object Pascal好像不支持C++的模板特性,这样智能指针恐怕是不能实现了,这东西可以和COM很好地搭配,一般情况下不用手动管理对象引用计数,也很大程度上降低了内存无意泄露的问题.
最后编辑dwing 最后编辑于 2007-05-17 10:26:15
TOP

回复:[M] Prelude to K.O. (4)

"Pascal可以用下面的方法定义一个指向任意一个类符合接口的成员函数:
TFunc = Function (A: DWORD): DWORD of object;"

真正深入学习编程语言就会理解每句代码是如何实现的.
C++几乎所有的代码我都能了解具体的实现方法.
但这句代码初看起来就有些问题.
C++中,用变量表示函数仅能使用函数指针.
这里的TFunc应该是指针吧.如果不是就会觉得很不可理解TFunc到底是什么结构.
如果是指针,这个值就是不固定的,因为许多类都可能符合这个接口,
而这些接口的地址都是不同的.
C++的函数指针只能指向全局或静态函数,指向某个非虚函数也有方法,
但指向虚函数的指针如何实现是不可想象的.
其实我们为什么只要这个成员函数呢,
C++中没遇到这个问题的原因是我们通常使用基类指针,
不必只要其中特定的某个成员函数.

我也不能说OP语言不优美,但我个人认为从语言本身的角度总体来看,确实与C++有差距.
最大的一点就是C/C++的预编译语言,尽管有人说它已经过时了,
但不得不说它使C/C++的开发适应能力达到极致.
借助预编译指令,C++工程是能够在主流平台编译的,现在许多开源工程都是如此.
C++的复杂和自由,还使人们经常能写出叹为观止的代码,智能指针就是一个例子.
C++不是没有跨平台能力,它是在源代码级跨平台的,而不是java的运行时跨平台.
不过就是因为源代码级跨平台太强了,int的范围竟不是固定的.
导致写一些核心函数时不敢直接用int,而是自己定义统一类型.(看来不可能十全十美)

java语言确实也和C++一样优美,可惜只是C++的一个子集(大致可以这么说).
其中的int是固定大小了,字符完全支持Unicode了.
但有一个致命的缺失--竟然不支持无符号整型,
有些时候就因为这个原因,程序不得不写的很复杂,效率很低.
当然一般只在系统/算法编程上.
所以说java只适合高层应用,不像C++那样应用广泛.
.NET要不是MS大力推广,能力上与C++比起来几乎没有优势.

嗯...感觉有些跑题了...

---
其实我也对Template没什么好印象,多数情况下确实用不到.
但"智能指针"是个特例,好像我只在这个地方用到了Template.
话说回来,"重载操作符"好像只是C++的特性吧-_-||
最后编辑dwing 最后编辑于 2007-05-17 11:49:18
TOP

回复:[M] Prelude to K.O. (4)

大致是这样实现的,增加一个共同的接口即可.

class WorkerThread;

class InterfaceA
{
public:
  virtual int DoSomething(WorkerThread *Thread) = 0;
};

class ModuleA : public InterfaceA
{
  // ...
  virtual int DoSomething(WorkerThread *Thread);
};

int ModuleA::DoSomething()
{
  // ...
}

class ModuleB : public InterfaceA
{
  // ...
  virtual int DoSomething(WorkerThread *Thread);
};

int ModuleB::DoSomething()
{
  // ...
}

class WorkerThread
{
  bool Attach(InterfaceA *one);
  // ...
};

bool WorkerThread::Attach(InterfaceA *one)
{
  // ...
  one->DoSomething(this);
  // ...
}

int main()
{
  // ...
  WorkerThread *workerthread = //...
  ModuleA *moda = //...
  ModuleB *modb = //...
  workerthread->Attach(moda);
  workerthread->Attach(modb);
  // ...
}

Delphi开始支持运算符重载?倒不如连模板一起支持了,
现在很多情况都是模板与运算符重载结合使用的.

无类型的思想最早是源于汇编的,而C语言是与汇编联系最紧密的高级语言.
所以无类型的思想才逐渐保留下来,这是自由的体现,也是指针发展的平台.

C++中不是所有类都有VTABLE的,
也许是OP的每个类都有VTABLE或如果使用了方法指针就自动加了VTABLE.
我认为不是简单地算一个偏移量就能解决的,
不继承基类,谁能保证类中同名方法在VTABLE中都是同样的位置?
最后编辑dwing 最后编辑于 2007-05-17 15:04:52
TOP

回复:[M] Prelude to K.O. (4)

是不是任意类是无意义的.
既然写了DoSomething方法,就是说要为WorkerThread而实现,
那么就要遵守WorkerThread的规则去继承InterfaceA又有何不妥呢?
而且我认为继承InterfaceA显式声明了要为WorkerThread而创建的类才是正途.
否则编译后所有的类的所有方法名称都要在可执行文件中保留.

InterfaceA只有一个虚函数,其他要成为Module的都要继承,
这是很正常的,许多C++大型工程,多继承(尤其是继承接口)是很常见的.
C++里的VTABLE可以说是动态调用方法中效率最高的.
如果像java那样还保留函数名的信息不但有运行效率问题,还容易被反编译.

以下代码编译通过(VC6+sp6):
void main()
{
        __asm
        {
                jmp next_
        }

        int a=123;

        __asm
        {
next_:
                nop
        }
}

不过我承认VC里的_emit指令确实不如Delphi里的db/dw/dd指令好用.
C++的inline函数和C/C++的宏都是OP没法做到的.
最后编辑dwing 最后编辑于 2007-05-17 16:38:33
TOP

回复:[M] Prelude to K.O. (4)

其实__asm根本就不是C/C++标准里的,
真正的高级语言标准是不允许嵌入汇编的,这影响到源代码的可移植性.
所以讨论inline汇编是不是标准,是不是扩展毫无意义.
VC的编译器基本上是Win32平台事实上的"标准",
GNU的编译器在Win32平台还无法与之抗衡.
所以请不要说GNU不能做的事是标准,VC能做的事是不标准.
很喜欢VC的"naked call",好像其他任何高级语言编译器都不支持这一很底层的特性.
这也是有人说VC"万能"的原因.
我认为您不要再对VC有什么偏见,
我是从VC6开始用的,VC可能也是从这时开始强大起来的,
VC2003更是达到了巅峰,据说对C++标准化的支持比GNU的还好一点,
XP操作系统和XP的补丁大部分都是用VC2003开发的.
累计到目前超过一半的游戏都是用VC开发的,目前使用VC6开发游戏的仍有不少.

"比如你敲一个对象,然后加"."旁边出来一个小窗口告诉你所有可用的方法和成员变量。"
这种特性还有必要说谁学谁吗,
VC有VAX做更高级的辅助功能,输入"b"就能智能提示出"bool",输入"class"就自动给出代码框架.
我不知道Delphi是不是有这些功能.如果没有,Delphi不去学就是优点吗?

-------------------------------------------------------

多层结构体的问题,下面的写法才是正确的:
struct StructD {int id;};
struct StructC {StructD sd;};
struct StructB {StructC sc;};
struct StructA {StructB sb;};

StructA sa;
StructD* psd = &sa.sb.sc.sd;
psd->id=1;
即使打开VC的最高警告级别也没有任何警告提示.
我想知道为什么说这是不标准的.

这与下面的写法看起来没有任何不美观的地方:
With StructA.StructB.StructC.StructD do
BEGIN
IntA:= 0;
END

其实OP实现那段代码,也要取StructD的指针.

-------------------------------------------------------

"一会儿用"."一会儿用"->"多麻烦啊"

晕了,微软提倡的匈牙利命名方法比这更麻烦,怎么还有人大力赞扬?
还有OP的"begin/end"比"{}",":="比"="等等更是麻烦...
其实很难能找到一个比C/C++更简洁的高级语言了.
还有一点值得一提,如果有VAX辅助,应该输入"->"却输入"."时会自动修正成"->".
VAX是我见过代码输入辅助软件中辅助能力最高,智能程度最高的,敲代码如行云流水一般.
比eclipse还强一点.

-------------------------------------------------------

我写过不知多少行代码,很难见到"深层结构",
真是如此,就应该看看结构设计的是否合理了.
最后编辑dwing 最后编辑于 2007-05-18 09:19:57
TOP

回复:[M] Prelude to K.O. (4)

本来我对标准化就不怎么看重,其实一旦某些东西用得广泛了,就是事实上的"标准化".
我说VC的编译器是事实上的标准并没有错,C++标准委员会里的人都有在MS做VS开发的.

"VC的跨asm段跳转"是很正常的,为什么要"爆掉"呢?

"不美观是因为多用了一个变量,多写了一行。"
实际上明明是需要这个变量的,OP在编译时也不例外,为什么要隐藏这句代码呢?
语言太高级就不是C/C++的特点了.
讨论语言历史,尤其是10年以前的历史没什么意义.
历史上,MacOS的图形界面比Windows的还好,难道为此我们就都去用MacOS?

"不小心把 == 写成 = 曾经浪费了你多少的时间?"
看来你不是成熟的C/C++开发人员,否则根本不会犯这么低级的错误.
而且VC在大多数情况下都能发现此问题,并给出警告.
如果在这个错误上浪费时间,那么在OP中":="和"="上浪费的时间也不会少.
"."和"->"的误用更不会遇到,何况编译时是一定能发现这种错误的.
当我熟悉C/C++时,把"."和"->"合并成"."看起来是很不合理的.
它把变量和指针的含义搞混了.

"任何需要处理大量关系数据的场合"
不必要的复杂设计才是导致深层结构的根本原因.

以上我所有关于语言的讨论宗旨是: Object Pascal语言是优美的, 但与C++相比还有差距.
MS放弃Pascal可能也是如此考虑的吧.
最后编辑dwing 最后编辑于 2007-05-18 11:51:24
TOP