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

[M] Prelude to K.O. (4.5) + 12楼(4.75)

[ 14783 查看 / 31 回复 ]

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

不做评价...直到开放SDK.
本主题由 管理员 深海蓝空 于 2007/6/9 14:49:31 执行 设置精华/取消 操作
分享 转发
TOP

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

原帖由 Prz 于 2007-6-3 0:00:00 发表
唔,对了,目前来说,CAS对于其它语言的兼容性并没有作太多妥协。

1. 对于一些Pascal原生的对象,CAS模块是将其作为基本元素直接传递的。比如,String对象,集合(set),记录类型(record)等。

2. Delphi提供的标准核心构件,也是被当作基本元素直接传递的。比如,文件(File),流(Stream)等。
(以上两点呼应我曾经提到过的,CAS仅仅是按照COM规范使用Interface实现模块代码分离,而不是完全的为COM而COM)

3. 比较重要的是,CAS模块与总线、模块和模块之间的过程调用没有Exception Firewall。
这样做的好处是能够为模块编写者提供全面的Debug信息——前提是,如果模块能安全的够接受异常对象并展示出其内部含有的信息;
但是,就像我上面提到的,不是所有的语言都对异常有完善的支持,尤其是对于C++来说,任何时候都可能抛出异常几乎是不能接受的.....


既然这样,我就不期望什么了,果然是太依赖delphi本身提供的各种"便利".
我还是去研读跨语言的COM好了.

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

另外,关于C++的异常.以下代码在很古老的VC6中就运行无误了.
包括构造函数异常,析构函数异常,嵌套异常,异常中的异常.

#include <stdio.h>
class C
{
public:
C(bool b) {if(b) throw new int(1);}
~C()  {throw new int(2);}
};
void func()
{
try{C c0(true);}
catch(int *e)
{
  printf("%d\n",*e); 
  C c1(false);
}
}
void main()
{
try{func();}
catch(int *e)

  printf("%d\n",*e); 
}
}

输出:
1
2
最后编辑dwing 最后编辑于 2007-06-03 10:19:17
TOP

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

原帖由 Prz 于 2007-6-3 15:55:00 发表

试试下面这段:
----

#include <stdio.h>
class Cx
{
public:
Cx() {throw new int(1);}
~Cx()  {throw new int(2);}
};

void main()
{
try{C c0;}
catch(int *e)
{
  printf("还没有到这里世界就太平了...||||");
}
}


VC6的运行结果:
还没有到这里世界就太平了...||||Press any key to continue

这个异常符合C++标准,为什么说M$擅自作了非标准的"修订"?
TOP

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

其实析构函数经常只做一些内存和资源释放,这些操作都是安全的,一般情况下都不会也不需要抛出异常.
如果确实要抛出异常,那要这么做:

#include <stdio.h>
class Cy
{
public:
        void testexcept() {throw new int(1);}
        ~Cy()
        {
                try { throw new int(2); }
                catch(int *e) { printf("%d",*e); }       
        }
};

void func()
{
        Cy c1;
        c1.testexcept();
}

void main()
{
        try{ func(); }
        catch(int *e) { printf("%d",*e); }
}

运行结果: 21

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

参考: 对象生死劫 - 构造函数和析构函数的异常
http://blog.csdn.net/tingsking18/archive/2007/03/05/1521296.aspx
最后编辑dwing 最后编辑于 2007-06-04 09:22:12
TOP

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

异常这东西我在写实际的程序中基本不用.因为既不使用抛出异常的库,自己也不需要抛出异常.
可能比较有用的异常是操作系统发出的,那个异常不是跨平台的,因此VC自己定义了一套__try/__except关键字来处理,这样就可以防止程序写无效指针等操作导致的立即退出.我不知道delphi如何做到这点的.
非console的大型工程一般都是写log文件的.log类只要做一下临界区处理就可以了.
TOP

回复: [M] Prelude to K.O. (4.5) + 12楼(4.75)

不仅如此,还必须在里面层层套用try...catch,头晕。

C++是非常灵活的语言,适当利用智能指针可保证内存自动回收,这样就不用层层嵌套try...catch了.
如果使用带有引用计数的share_ptr或句柄模板类,那基本不需要手动delete任何对象了.
话说回来,delphi不也会面临层层套用try...catch的问题吗?

似乎C++在析构时截获异常只能打印处理,然后丢弃,更像是在“帮助调试”。

C++异常类可以设计成异常链的形式继续抛给上层.
不过构造异常类对象也有可以抛出异常,这样上层得到的异常对象要么不存在,要么描述异常的信息不完整,delphi也应该会遇到这种问题.

因此绝大部分的异常都是为调试服务的,正常运行中的程序流程很少会抛出异常。

异常主要不是用来调试的,调试不能因异常而停止后面代码的测试.
高效的调试方法应该是设置断点,assert,单步执行和查看变量.
异常是一种更方便快捷地处理无法继续运行的问题的机制.

从设计的角度,你很难保证析构时调用的所有函数都不抛出异常,不论什么原因。

析构确实没什么理由需要抛出异常,所有释放资源的函数都不需要抛出异常.
除了资源回收,析构还需要做什么呢?
我的原则是构造和析构都仅仅对成员变量做最基本的初始化和释放,不把复杂的工作放到构造和析构中.
如果真对析构中调用的函数不放心,就用cache(...)忽略掉或做个log好了.如果资源释放都不能如愿,对象析构也就没什么意义了.
最后编辑dwing 最后编辑于 2007-06-11 18:26:23
TOP

回复: [M] Prelude to K.O. (4.5) + 12楼(4.75)

汗,您讲的这些我并没有认同我说的有误,您对C++的理解和我对OP的理解半斤八两.我只好耐心地解释:

据我有限的理解,所谓的智能指针仅仅是保证在对象不再被引用的时候自动“析构”而已,和异常处理风马牛不相及,不用try...catch一样会挂。
如有错误,请纠正。

只要保证析构不抛出异常即可避免嵌套try...catch,析构不抛出异常这本来就是一条规定,就像判断指针是否为空之前不要随便赋值一样.C++的灵活使它能做到许多其他语言不能做到的很难想象的复杂功能,但也会出现滥用的后果,不能说核能危险我们就不去开发它.
VC的__try/__except机制才可以做到从出现异常的地方再次继续运行.不过我承认这个机制很危险,一般是没人用的.所以只有认为出现不可继续运行的严重问题时才抛出异常.

话说回来,delphi不也会面临层层套用try...catch的问题吗?

您可能没理解这句话的意思.
单层try...catch机制是不顾后果的,一旦抛出异常,异常后面的资源释放都无法继续执行,delphi怎么会避免呢?

这个时候如果发生异常,抛出的当然将是另一个的异常。

这就是我所说的一种情况,这里的"另一个异常"就没有前一个异常的信息了,用异常来调试也就"信息不完整"了.delphi构造任何异常都是要分配内存的,如果分配内存出现异常,则构造任何异常都会出错,最后即使能catch到,也只能得到分配内存错误的异常,而没有最初抛出的异常了.

如果程序遇到异常而可以不停止调试,那就证明程序可以继续运行下去,那么也就没有必要使用异常

这么说,异常就不是用来调试的.

(反映到实际使用中,比如分配、调用资源的失败,都可以用返回值,没有必要使用异常);

呵呵,在实际使用中,异常经常用来解决"分配、调用资源的失败"而无法继续运行后面的代码,这些才是典型的"异常"并跳出,不必每次都判断返回值并做频繁的错误处理.如果出现一般错误,才应该用返回值.

我相信您的描述可以自圆其说,但是,你不能将自己的意愿强迫到别人的头上。别人怎么提供别人的实现,这是与您怎么实现您的对象是非常不同的事情。

合作写程序如果不做出一些规范,那才是灾难.

Delphi和C++异常处理对于一个人的几万行程序来说,基本没有区别。但是对于多人,特别是以松散方式合作的组来说,C++异常的scalability要差得多(这里的意思是,随着规模的扩大而导致可用性的快速降低),这个是不争的事实。

天啊,您在哪里听说的无稽之谈,不妨给个参考让我好好拜读一下.没准我还真去"投靠"delphi了呢:)

但是问题是,无数的历史事实证明,独裁的结果肯定是快速灭亡,因此不是一个解决问题的办法。

C++是有标准并广泛存在的,delphi才有些独裁...这句话赠送给您更合适:)
最后编辑dwing 最后编辑于 2007-06-12 09:34:18
TOP

回复: [M] Prelude to K.O. (4.5) + 12楼(4.75)

模棱两可。请正面回答我的问题:您前篇里面企图把智能指针和异常处理混淆在一起,我认为是不相干的,我到底是错了还是对了?

智能指针的一个好处是能很好地处理异常时资源无法完全释放的问题.
在保证析构不向外抛出异常的情况下,借用智能指针的自动析构来释放资源是很安全便捷的.
而且也可在构造函数中抛出异常时自动释放资源.
而显式地释放资源就容易被try...catch机制忽略掉,而析构是不会忽略的.

就用你自己的切身说法,析构仅仅是释放资源。那么异常发生,自然是比释放资源更严重的事情发生了,继续释放资源还有意义吗?

我可不这么认为,如果真比释放资源还重要,那就像C++那样无法处理异常就退出好了.
例如我要读取文件中的内容并显示出来,这里就有可能出现许多无法继续执行的情况,如文件不存在,文件格式不正确,文件无法读取等等,
每次都写一堆if...else并且每次都要写一堆释放资源的代码是很烦琐的,这种情况就适合抛出异常,并在catch中统一释放资源.
这都不是致命错误,释放资源也是有意义的.

你用一个C++和Delphi以至于任何一种程序都会出现的问题,明显没有说明任何的作用。

我可没说C++在这个地方有优势,而是您说delphi有优势,而我反驳了而已,并没有C++在这个地方更好的意思.

只要你不独裁,我尊重你的看法

我可不是说要独裁,delphi的RAD是VC不及的地方,但要说写系统或底层程序,C/C++更适合.
(C/C++是能让编程者懂得每个步骤编译器是如何处理的对编程者要求比较高的语言.)
这不是我一个人的观点,而是事实上确实如此,我所见过的所有的操作系统,编解码器都使用ASM/C/C++,这是我"独裁"的结果吗?

概念错误,"分配、调用资源的失败"绝对不是无法继续运行的错误。

如果内存池无法分配,资源句柄无法分配,我想后面会有一大片代码无法继续运行了.

使用Delphi的大中型项目中随处都找得到异常的使用;请找出使用C++的大中型工程中使用异常的例子?

我见过许多写的很优秀的C++库都使用了异常,包括STL,BOOST,MFC等等.
在C++大中型工程中没遇到异常也是有许多原因的:
1.底层代码中很少遇到需要抛出异常的情况,像java那样高层语言,异常属于家常便饭了.
2.C++比较复杂,异常属于高级特性,非精通者不敢使用.
3.C/C++的工程许多都要考虑跨平台,而不可能保证异常一定被系统支持的.
4.使用异常容易使开发人员产生依赖感,对自己的代码不负责任.

因此相对您,我更不像独裁者

那么希望到开放接口时,不要像前面说的那样"CAS对于其它语言的兼容性并没有作太多妥协。"
(看看微软,虽然比较"独裁",但它的COM接口是非常开放的,从汇编到js脚本都能调用其接口.)
最后编辑dwing 最后编辑于 2007-06-12 12:02:02
TOP

回复: [M] Prelude to K.O. (4.5) + 12楼(4.75)

很遗憾的发现,你根本没有仔细阅读你自己在前面贴出来的那边CSDN的Blog。
构造异常的时候自动释放对象是Delphi的基本功能,不需要外加"智能"。

自动释放对象只是针对成员变量在析构函数中释放吧.

你当然没有说C++有优势了,而且还没明白我的意思,我说的就是你的反驳方法无效。

不要因为你举了一个无法说明问题的例子就说我的反驳无效.

请不要偷换概念:“不妥协”绝对不是“独裁”。
当然,对于M$我只有不好意思地说"Suck It"了。
M$不是一贯的以自己为标准,然后希望别人"妥协"吗......

我可没说"不妥协"是"独裁",不要妄加推断.
没有正当理由排斥MS,是无法让人信服的.
不要总是提到"独裁者",你又不想针对我,那你想说明什么?
我不清楚你"不妥协"的是什么?
还有,不要总拿delphi和C++比较,二者不是同一层次的东西,C++不是MS独占的.
不要把话题转得太远,本楼辩论焦点是为什么delphi/object pascal的接口不去支持C++.是技术原因还是个人原因.
最后编辑dwing 最后编辑于 2007-06-13 09:18:42
TOP