昨晚在家看了一集《武林外传》,说的是白展堂给捕快小六教武功,就教了扎马步,郭芙蓉给莫小贝教武功,就教了个转圈圈(什么什么八卦掌)。结果莫小贝和小六比武,小六始终扎着马步,莫小贝就在他旁边转圈圈,硬是把两个人累趴下了。
虽然挺可笑,但也反映了一个问题。行为应该取决于目的,虽然那些招式号称武功,但不能制敌,不如上去捶他一顿。而我们做技术设计的,最容易犯这个毛病了,刚刚学了个新方法,新技巧,新模式,就急不可耐的用了。就像上学时刚学了个公式,做作业时就拼命用,也不管是不是应该用。
我以为,其实面向对象设计的威力之所在,是设计的原语更接近现实世界,有些书中提到“隐喻”,其实就是让我们把设计放到生活中来,找到类似的例子,再反馈到设计中去,如此反复,以完善我们的设计。而这其中,恐怕最重要的要素就是对象的职责和彼此协作机制。
崔刚 2007-11-23
在我的旧文中,曾经提到在 C++ 中实现 Java 的 final 功能,但每次都要写一个基类比较麻烦,今次用模板把它加强。
1 template<class T>
2 class final{
3 friend T;
4 private:
5 final(){};
6 };
7
8 class MyTest : public virtual final<MyTest>{
9 public:
10 MyTest(){};
11 };
这样以后就可以直接继承模板类 final<T>,而不用每次都写一个类。
在这里顺便说一下,为什么一定要虚继承,假设我们有
1 class test : public MyTest{};
如果上面不是虚继承,那么 final 类的构造函数由 MyTest 的构造函数负责调用,因为是友元类,则调用成功,无法阻止 test 实例化。而一旦声明为虚继承,MyTest 不再负责调用 final 的构造函数,而由 test 来调用,那么因为不是友元类,实例化将失败,编译出错,提示不能访问私有的构造函数。
这里给出一个方法,实现对某个方法调用者的限制。
1 class TestBase{
2 int data;
3 protected:
4 void write(){};
5 public:
6 void read(){};
7 };
8
9 class Test:public TestBase{
10 friend class client;
11 };
12
13 Test test;
14 TestBase test2;
15
16 class client{
17 public:
18 void dowith(){
19 test.write();
20 //test2.write();
21 };
22 };
23 //-----------
24 int main()
25 {
26 client c;
27 c.dowith();
28 return 0;
29 }
这里将写方法声明为保护的,对外界不可访问。派生类Test的作用仅仅是将友元类进行声明。
=======================
妙妙妙!
使用这个方法,就可以对类的私有函数进行单元测试了!!!!
JeansBer
倒霉起来,什么都挡不住,现在只能用左手打字了。自从鼠标和筷子换到了左手,突然有重获新生的感觉,我真切地感到自己还有很多的事情都不会,当米饭被左手的勺子弄得满桌子都是的时候,我仿佛回到和女儿一样的年纪。
不知道大家有没有在前进的路上踌躇,你还有至少一半的潜力没有开发,当你习惯了右手,不要忘记你还有左手。
崔刚 2007-11-19 左手草就
===========================
支持!今天起用左手鼠标--陶华
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
难得崔兄如此豁达!真应该向你学习!人生已经如此明镜,还有什么困难挫折,能挡在我们面前呢? -- 张进
=======================
呵呵,以前也是手伤了,用左手吃了一个月饭,之后也经常有意使用左手,再后来听说这样对神经不好,会引起混乱,觉的有一定道理,也渐少用了。
--bingo
==========================
当你是一个另类时,你会觉得似乎和周围的人有点格格不入,总觉得有人会耻笑你,虽然没有人笑你;我小时候是用左手的,写字、吃饭、砍柴,直到初二吧!小时候扳手力,我搞不定其他小朋友,因为大家都是用右手;打乒乓球我用左手,时不时可以来个出人意料的扣杀,用右手的人是很难接招的。打篮球我也是用左手,很多很多,但在我的成长过程中,我都在强迫自己用右手,导致左右手都发育不良,还好女朋友(现在是老婆了)一直称赞我脑袋瓜特好使,让我多少有一点欣慰。若我的后代也遗传了我的左撇子,我会告诉他自然发展吧!
——钟遥
**********************************
呵呵,我上高中的时候,由于一次右手腕受伤,被迫改用左手运球,投篮;随后也就养成了左右手平衡发展的习惯。虽然我左手投篮的命中率总是超不过右手,但是平衡发展可以让自己的缺点不是那么明显和致命,有时甚至可以转化成优点。
--杨晓涛
/////////////////////////////////////////////////////
感谢大家跟帖,其实用左手挺好的,锻炼一下,看看什么时候可以左右互搏。 :) 崔刚 2007-11-19
================
忘了对崔刚的伤势表示慰问,肿了呢!
伤成这样都如此乐观,称赞称赞!就当是因祸得福吧!借此机会开拓自己的另一半!
——钟遥
Martin Flower在《重构》里提到空对象模式,对于从容器中查找失败需要返回引用时,可以使用,同时我觉的对于空指针调用也有一定作用,试举一例:
1 #include <iostream>
2
3 class Mail{
4 public:
5 virtual void print()
6 {std::cout<<"Hello!"<<std::endl;};
7 void* operator new(size_t);
8 };
9
10 class NullMail{
11 NullMail(){};
12 static NullMail inst;
13 public:
14 virtual void print(){
15 using namespace std;
16 cout<<"error! You can't access a NULL object!"<<endl;
17 }
18 static NullMail& GetInst(){return inst;};
19 };
20
21 NullMail NullMail::inst;
22
23 void* Mail::operator new(size_t){
24 return &NullMail::GetInst();
25 }
26
27 Mail* GetMailPtr(){
28 return NULL;
29 }
30
31 Mail& GetMailRef(){
32 return (Mail&)NullMail::GetInst();
33 }
34
35 //
36
37 Mail* ptr_Mail = GetMailPtr();
38 Mail& ref_Mail = GetMailRef();
39 //ptr_Mail->print();
40 ref_Mail.print();
当我们返回一个空指针给调用者,如果他没有判断,那就会发生系统崩溃,而我们返回一个空对象的引用就可以避免这一点。
另外一个附加的有趣现象,你认为下面的调用会输出什么信息?
1
2 ptr_Mail = new Mail;
3 ptr_Mail ->print();
4 ref_Mail.print();
正确的答案是:
1 Hello!
2 Hello!
因为Mail的缺省构造函数将自己的vptr填给了NullMail单例。
=====================
一个问题,是不是Mail的每个公共接口,NullMail都要去实现一下? --th
//除非实在没有必要,的确应当实现一下所有的公有虚方法。cuigang,2007-11-08
=====================
“对于从容器中查找失败需要返回引用时”,下午刚刚碰到一个这样的问题。 jb
昨天看了一下除颤的代码,发现里面类的框架里有一个NoCopy(类似名字)的类,将拷贝构造函数和赋值运算符声明为私有的,那么继承于这个类的派生类也不能被克隆,注释中强调要私有继承,其实如何继承都可以,只要派生类不在public部分重新定义拷贝构造函数和赋值运算符就可以,另外也不必单独写一个类,这个声明写到基类就可以了。
看到这个我又想到一些类似的小技巧,比如单件模式,其实就是将缺省构造函数声明为私有,以限制实例化。例如还有:
1、强制必须动态分配,可以将析构函数声明为私有,同时提供free方法(因为不能delete)。
2、禁止动态分配,将new方法声明为私有。
3、禁止继承,继承一个类(最好虚继承),这个类的构造函数是私有的,并且它的友元类是派生类。这个比较复杂,代码示例如下
class final{
friend class MyTest;
private:
final(){};
};
class MyTest : public virtual final{
public:
MyTest(){};
};
这样就实现了Java的Final功能。
以气为宗还是以剑为宗?
话说华山派因气剑之争分为二宗,一者以修习内功心法见长,是为气宗,一者以钻研剑法招式为本,是为剑宗。二宗意识形态不同,哪能共存,某年某月某日两派华山一役,剑宗尽灭。但老金似乎并不认为气宗就一定高过剑宗,又让令狐冲学了剑宗本事后突飞猛进。到底哪个才是末学,老金并没有给出答案。
程序员往往也面临这个抉择。
======================
我不喜欢依靠外物,我选气宗。
--彭建军
===================
个人学气功,集体练剑阵--陶华
=================
考虑这个问题很久了,想到两句话:一个是《老子》里的“以正治国,以奇用兵”,一个是《三国》里的“用兵之道,一正一奇,正者持之,奇者胜之”。引申到软件里,我认为能固化能传授的经验和工具(如正向设计,规范流程,代码熟悉)就是正,反之非常依靠经验(如查死机问题,打补丁)就是奇。正是奇的根本,没有正的奇就是旁门左道。bingo
============================
孤孤单单一个人,走在丽影双双的街头,
忘了我在找什么,等待明天还是往回走?
总是在失去以后才想再拥有
......
这个问题我都想的很累了,很想看到大家的想法,
顶起来!希望看到更精彩的高论!
JIn CHuang(张进)
/**************************************/
气剑之争,实是寻求武学的终极之道,究竟是个人修为重要,还是研习招式重要。武学自古有内外之分,少林武当皆以内家气功见长,但也有铁砂掌之类的外家招式,令狐冲的独孤九剑可能就是剑法巅峰之学了,从也不见小李探花用什么内力。可见内外家都有绝顶高手,但深入看,其实这些名家无不内外兼修,难以想象仅有内力却无招数,那如何制敌?或徒有高招但绵而无力,敌何惧之? 其实便如玩暗黑系游戏,给人物加属性一样,每次只有5个点,你说加什么属性?
崔刚 2007-10-31
*/
===================================
顶!
顺便问问,“葵花宝典”很是厉害,是内功还招式,或是兼而有之?mosj
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
”葵花宝典“是内功吧,“辟邪剑法”是招式!令狐冲最后能敌得过岳不群还不是靠收了桃谷六仙的内力,最后又习了少林易筋经的结果。所以麻,还是得靠内外兼修!这才是武学大家!
Ftz
////////////////////////////////////////////////////////////////
问各位玩过星际类似游戏的,你们认为造更多的兵重要还是升科技重要? 崔刚,2007-11-1
#########################
不要执著于答案,跟郭富城一起动起来吧!要兵不要科技,就是无源之水;要科技不要兵,就是竹篮打水。 靳波
============================
狂占矿,狂造兵,狂升级,狂骚扰,狂操作,最后搞死他。 --彭建军
=======================
把所有能用的都用上,不留任何闲置资源--陶华
============================
升科技或者造兵都可能赢,唯一必输的就是什么都不做。
--王祁
===================================
要隐喻练武,拿朴素的话来讲,我认为,一个程序员的成长可分为如下六个阶段:
第一阶段
熟练地使用某种语言。这就相当于练武中的套路和架式这些表面的东西。
第二阶段
精通基于某种平台的接口(例如我们现在常用的Win 32的API函数)以及所对应语言的自身的库函数。到达这个阶段后,也就相当于可以进行真实散打对练了,可以真正地在实践中做些应用。
第三阶段
能深入地了解某个平台系统的底层,已经具有了初级的内功的能力,也就是“手中有剑,心中无剑”。
第四阶级
能直接在平台上进行比较深层次的开发。基本上,能达到这个层次就可以说是进入了高层次。这时进入了高级内功的修炼。这时已经不再有语言的束缚,语言只是一种工具,即使要用自己不会的语言进行开发,也只是简单地熟悉一下,就手到擒来。
第五阶级
已经不再局限于简单的技术上的问题了,而是能从全局上把握和设计一个比较大的系统体系结构,从内核到外层界面。可以说是“手中无剑,心中有剑”。到了这个阶段以后,能对市面上的任何软件进行剖析,并能按自己的要求进行设计,不论多复杂的软件,只要有充足的时间,也一定能设计出来。
第六阶级
是最高的境界,达到“无招胜有招”。这时候,任何问题就纯粹变成了一个思路的问题,不是用什么代码就能表示的。也就是“手中无剑,心中也无剑”。此时,对于练功的人来说,他已不用再去学什么少林拳,只是在旁看一下少林拳的对战,就能把此拳拿来就用。这就是真正的大师级的人物。
——钟遥,2007.11.1
++++++++++++++++++++++++++++++
有人在乎外表风度,有人在意内心温度,我选择内外兼修--立朗商务男装(杨晓涛 引)
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
不管是内家功夫,还是外加功夫,高手们无不兼容并包,但最终所有高手倚重的往往只有一个.
鸠摩智算是人中龙凤,见什么学什么?强炼少林寺72项绝技,结果还是比不过乔峰的降龙十八掌.乔峰
自幼得到少林真传,也就是基本功很好,所以就算是只用太祖长拳,就在聚贤庄做到无人能敌.
段誉属于另外一种炼剑宗的极端,本来不会武功,,偏偏造化让他懂了六脉神剑,就这一个练到运用自如,就能打败很多高手.
所以,内外兼容并包,没有错,但是最终的方向只能有一个,否则他就是神了.
zhangjin
/**************************************/
/*
感谢各位捧场,看了各位的跟帖,特别是钟遥竟然写的比主贴还长,真是敬佩敬佩。看来各位均觉得内外兼修,兼容并包是正途,之后钟遥就觉得招式已为末学,而张进就说只要选一个就好。但我以为无论是御气,还是剑法,终有尽头。就好像星际,当你人口达到上限,科技全部升满,操作已登峰造极,你练什么?到最后高手对决,恐怕拼的还是智慧、勇气和自信。
崔刚 2007-11-02
*/
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
我最认同钟遥兄的观点,我好像记得梁肇新也有此观点吧!
其次,才是我的大缪!
哈哈,哈哈!看来我们部门真是卧虎藏龙,大家已经登封造极,开始讨论学什么了!
不过这是一个监护软件的镇山之贴,此贴留名,幸甚!
jin chuang
一个问题的讨论
今天在QQ里跟大家讨论了一个问题,虽然没有结论,但是还是贴出来留个记号。
崔刚(崔刚) 2007-10-25 16:18:55
如何通过基类指针调用派生类特有方法,前提是不允许强制转换指针类型?
例如有基类 class base{};
派生类
class derive:public base{
public:
int A();
}
我得到了一个base* 类型的指针 derive_ptr,但它指向derive类型对象,我如何调用方法 derive::A(), 不可以
((derive*)derive_ptr)->A();
李奇兵(李奇兵) 2007-10-25 16:20:17
把方法A()申明为虚的
陶华(陶华) 2007-10-25 16:20:52
除非基类有这个虚接口
李奇兵(李奇兵) 2007-10-25 16:20:55
把方法A()申明为虚的,在Base定义一个。
向官文(向官文) 2007-10-25 16:21:16
用函数指针应该可以实现吧
陈道生(陈道生) 2007-10-25 16:22:46
没方法
崔刚(崔刚) 2007-10-25 16:22:27
呵呵,如果base类有几十个派生类,每个派生类都有不同的特有方法,那么在基类中就会存在几十个虚方法,而每个派生类只实现一个,其它全部不实现,
这样是不是不太好??
李伟(监护)(李伟(监护)) 2007-10-25 16:23:25
如果是public的,基类应该声明吧
张建生(张建生) 2007-10-25 16:23:57
这样的话该函术确实不应该在基类里面定义
基类里面只定义共有的
靳波(靳波) 2007-10-25 16:23:47
这个问题的答案肯定很有技巧,但我认为这种技巧太花哨,不知道也没关系
陶华(陶华) 2007-10-25 16:24:49
崔刚,你那样定义是违反替换原则的
向官文(向官文) 2007-10-25 16:25:02
咱们的消息映射机制就是用基类的函数指针调派生类的成员函数
李伟(监护)(李伟(监护)) 2007-10-25 16:25:02
还是想知道。。
莫书健(莫书健) 2007-10-25 16:25:22
上面那段代码会不会运行是对的?
只是这样强制转换不是很符合编码规范
崔刚(崔刚) 2007-10-25 16:25:28
呵呵,不要怀疑我的问题的实用性
彭建军(彭建军) 2007-10-25 16:26:34
对于这个问题,C++的标准解决方法应该是dynamic_cast
靳波(靳波) 2007-10-25 16:26:15
cast也是类型转换
莫书健(莫书健) 2007-10-25 16:27:41
加不加dynamic_cast之类的,运行效果应该一样
彭建军(彭建军) 2007-10-25 16:29:18
是类型转换,但那是C++标准的转换方式。
向官文(向官文) 2007-10-25 16:30:45
dynamic_cast 据说会损失执行期效率
靳波(靳波) 2007-10-25 16:31:33
dynamic是在运行时进行转换,所以不是据说,是肯定会损失执行期效率。
靳波(靳波) 2007-10-25 16:36:22
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
};
class Derive : public Base
{
public:
int A(){cout<< "Derive::A()\n"; return 0;}
};
union Amazing
{
Base* pBase;
Derive* pDerive;
};
int _tmain(int argc, _TCHAR* argv[])
{
Base* derive_prt = new Derive;
Amazing trick;
trick.pBase = derive_prt;
trick.pDerive->A();
delete derive_prt;
return 0;
}
向官文(向官文) 2007-10-25 16:37:45
typedef void (base:: *BasefnPtr) ();
BasefnPtr fn_ptr = &derive::A;
然后用基类的指针去调
(pBase->*fn_ptr)();
我看高端里消息响应函数就这样调
没理解错吧 ;)
崔刚(崔刚) 2007-10-25 16:39:09
同志们,跑题了
1、不能强制转换,标准的强制转换也不行。
2、不是把派生类指针转成基类指针,那样是没问题的。我说的是把基类指针转成派生类指针。
杨晓涛(杨晓涛) 2007-10-25 16:40:14
靳波的方法挺有创意的,呵呵
靳波(靳波) 2007-10-25 16:40:45
:)
莫书健(莫书健) 2007-10-25 16:41:37
jinbo的方法有什么优点?
崔刚(崔刚) 2007-10-25 16:41:46
靳波太搞笑了,这样写不可维护
靳波(靳波) 2007-10-25 16:41:41
这个方法太危险
崔刚(崔刚) 2007-10-25 16:42:13
变相的强制转换,不合格,0分
莫书健(莫书健) 2007-10-25 16:43:34
cuigang的需求估计没有解决方法
陶华(陶华) 2007-10-25 16:44:57
需求评审不通过
崔刚(崔刚) 2007-10-25 16:44:40
问题本身是没有解的,但是迂回的方法有,比如IoControl或者高端中ControlModule的方法就是一种,但是不是有其它更好的办法呢?
崔刚(崔刚) 2007-10-25 16:45:34
visitor 模式也提供了一种方法,但是太麻烦,本质上和 IoControl 没什么区别。
张进(张进) 2007-10-25 16:48:45
还有一种方法,把编译器作者拉出来打,狂打,直到他搞定为止!
陈道生(陈道生) 2007-10-25 16:48:57
有点像已经知道方法名和参数,如何调用实例对应的方法,在c++中无解,在其他语言大放异彩(java,c#),都是要具有元编程能力的语言才行.
崔刚(崔刚) 2007-10-25 16:48:26
我需要一种安全方便又易于维护的办法,不要急着回答
崔刚(崔刚) 2007-10-25 16:49:23
难道我们真的离不开强制转换??
莫书健(莫书健) 2007-10-25 16:52:18
如果想调用派生类的方法,就要使用虚函数,
设计基类是要充分抽象,尽量想到种种情况
向官文(向官文) 2007-10-25 16:53:01
崔刚好像对强制转换深恶痛绝啊~
崔刚(崔刚) 2007-10-25 16:52:46
我认为依靠继承的方法不可取
莫书健(莫书健) 2007-10-25 16:53:19
实在不行,就将就强制一把,我想也可以容忍的
杨晓涛(杨晓涛) 2007-10-25 16:54:05
类本身也需要细化,寄希望一个类包含所有的接口是不现实的;
粗暴的将所有功能放在一个类中,也是不美观的,不招人喜欢的
崔刚(崔刚) 2007-10-25 16:53:45
不是我厌恶强制而是强制不安全,维护代码时可能发生不可意料的问题。
靳波(靳波) 2007-10-25 16:53:57
既然你已经有答案,不如公布出来让大家参详参详。
崔刚(崔刚) 2007-10-25 16:54:54
我没有答案,有的话就给你们上课了
莫书健(莫书健) 2007-10-25 16:56:11
这个课题就叫“崔刚猜想”吧
陶华(陶华) 2007-10-25 16:58:27
给C++标准委员会提个需求
崔刚(崔刚) 2007-10-25 16:59:27
另,dynamic_case<> 需要编译器支持 RTTI
向官文(向官文) 2007-10-25 17:04:51
C++这门静态语言解决这个执行期的动态问题恐怕无解
也许出路在第三方的接口上吧
崔刚(崔刚) 2007-10-25 17:05:55
换句话说,大家是不是认为,在目前阶段,象ControlModule和IoControl这样的接口是相对合适的喽。
崔刚(崔刚) 2007-10-25 17:13:41
2007年10月8日,汪胜平在他的工作日志里写道:
关于ControlModule型接口
这种类型的接口有以下好处:
1、降低编译依赖性。
2、如果模块A通过接口ControlModule依赖模块B,当模块B不存在时,理论上模块A仍然可以正常工作。
当然它也有一个不好的地方,那就是本来简单的调用关系,因为这个接口的引入变得复杂一些了。
但是,这两个好处需要小心使用才能保证。
1、没有函数名的依赖,但是并不代表就没有编译依赖了。比较典型的是ID的依赖。ID在模块B中被定义。在A中直接包含
B的头文件。不过这种编译依赖可以由第三方定义ID来解决。
2、如果需要传递的信息比较多,我们最容易想到的方法是定义一个结构体来传递相关信息。这个结构体如果由B来定义,
那么A又落入了在编译上依赖B的陷阱。
3、如果A在调用时没有考虑好B不存在怎样处理,那么ControlModule的第二个好处就体现不出来。
对于ControlModule型接口。我觉得要慎用,它不是万能的。某些时候,虚函数也许更方便。
=================================
这是一个典型的C方式函数。我觉得如果是通用的接口,可以用多态,如果是特殊函数,这样写纯属找茬。//崔刚 2007-10-12
=================================
ControlModule这类的接口,简单问题复杂化,难道只是为了
“降低编译依赖性”?这会不会是我们软件部附加上去的想法,
这类接口经常用于驱动接口(请参看linux\windows,
还有我们的mmos驱动模型),
我想最初这样做的理由会不会是这样:
1)为了减少接口个数。
2)统一属性设置/获取接口。
至少在驱动是这样的。
比如:
set_property1();
set_property2();
:
:
set_propertyN();
减少为一个
#define ID_PROPERTY_1 0
#define ID_PROPERTY_2 1
:
:
#define ID_PROPERTY_N n
Control( property_id, ...);
mosj
夏恒星(夏恒星) 2007-10-25 17:37:29
呵呵,原来这样的问题并不只有我遇到,俺在代码中加了注释:
//注意: 将基类指针强制转换为派生类指针并不可取
//但是此处要使用协议各层提供的非基类提供的接口
//能不能从设计上避免?
mTopProtocol = (CUartCommProtocol* )(m_pProtocolStack->GetSpecifiedLayer(UART_COMM_PROTOCOL));
崔刚(崔刚) 2007-10-25 17:44:02
这种应用更常见的地方是,把不同的派生类放到共同基类类型的指针容器里,然后把这个基类指针取出来,再干一些派生类的事情。
崔刚(崔刚) 2007-10-25 17:46:11
随便在高端里copy一段代码给大家看:
MSpinBox* pSB;
pSB = (MSpinBox*)GetWindowItem(IDC_CO_SPIN_TB_HI);
INT32 value = pSB->GetIntCur();
汪胜平(汪胜平) 2007-10-25 17:53:20
我觉得这种类型的接口比ControlModule强,
虽然这些接口会增加编译期依赖。
崔刚(崔刚) 2007-10-25 17:53:40
这就见仁见智了。
崔刚(崔刚) 2007-10-25 17:58:59
下班前,抄一段《JAVA编程思想》的话给各位共勉,包括发炎的没发炎但吃了药的。
http://vss2/sites/jhsoftware/Lists/List13/Attachments/768/ThinkJava.bmp
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
太“行而上”了!不过监护软件部真是不可小觑啊! 张进
/*******************************************/
/*
我不认为这是一个“形而上”的问题,或者一个智力游戏,它有着广泛的用途,否则不会有这么多的讨论和解决方案。昨天晚上回家查了一下,“向下转型”的确是我们要在设计中避免的,但在实际设计却经常面临,目前所有语言基本都支持到dymanicv_case<>的地步,而这却需要RTTI的支持,虽然其他高级语言比如C#,Java,Python都在语言级别提供象“反射”等方式来解决这个问题的超集,但是此种“元类”的语言特性违背了C++的精神,想必无论如何也不会出现在C++里,因为效率的牺牲和运行时存储的需求应该也不适用于目前的嵌入式设备。
反过来再想想,我们何必要求非常安全的途径解决这样的问题。C++/C本来就是一种弱类型语言,不安全的特性比比皆是,所以动态强制转换未必不是一个正途。
另外,对于汪胜平最后说出的问题,我觉得ControlModule之类的写法可以用这种强制转换的方式解决,当然孰优孰劣就留给各位去判别了。
崔刚 2007-10-26
*/
昨天是教师节,自离开讲台以来,再也未因此发过钱财,不觉有些怀念,所以今天就说说老师这个职业。师者,所以传道授业解惑也。我以为,昌黎先生的三种,传道为先,授业为本,解惑为末。
有些事情说着容易做着难,道是什么,如何传,可以大胆的说,没人知道。所以传道变成了悟道,同学们,你们要悟。老师们是不知道什么是道,即便知道,也说不出来,即便能说出来,你也听不明白,没办法传给你。正所谓,师傅引进门,修行在个人。
反过头来看企业的员工培养,面临同样的问题。通常的企业都是师徒制,师傅带徒弟。遇到一个好师傅尤为重要,当年郭靖跟着江南七怪的时候,乏见成效,而全真派的牛鼻子马钰一来,郭靖就突飞猛进,害得柯镇恶还以为我们的靖哥哥跟了梅超风走歪门邪道呢。那么,原因何在呢?教不得法也。大凡武林正派甚至泰山北斗犹如少林武当,均以内功心法见长,内力修为方为习武之根本,而招式均乃奇技淫巧,这也就是妖怪宝贝多的缘故了。马钰毕竟是聪慧之人,捡了个便宜。
修习内功岂是速成之径,所以我们急功近利的想法就是告诉他怎么做,而不是为什么,岂知欲速则不达。所以企业培养人才,应该着重培养他的内力,不要只顾眼前。师傅们不管得道与否,均需谨记,传道为先,虽然你可能说不出,讲不明。
因为师范生缘故,学过一阵心理学,知道马斯洛的层次需要,其大致是是说,人的需要分作5层,自高至低依次是自我实现尊重爱与归属安全生存
而人的需要往往是逐渐升高的,只有下一层需要得到满足,然后才会产生上一层需要。这里谈它,不是想在这里丢书包,只是想说,马斯洛说的并不全对,因为在我们生活中,不乏有越层的需要,比如饥饿贫困但是深深爱着公主的流浪汉,四处奔波隐姓埋名的共产党地下工作者,贫民窟里志存高远的年轻人,当然也有一些患者也不满足。
不过有越层需要的人往往都是偏执狂,他的这种追求(我觉得已经不能称为需要了)对他而言大多成本很高。如果他努力且幸运,可能会成为一个了不起的人,否则会表现出严重的抑郁症甚至精神分裂。
其实,追求软件的质量也是类似的,这些就是CMM要分级的原因,而且不允许越级评审,因为他们认为越级是危险的。大跃进式的发展是代价高昂而且危险的(以下均指一般情况,不包括特例),如果你本次项目的千行故障率是12,你想把它在下次项目降到8甚至6,基本上是属于幻想,那需要付出血的代价。
赶英超美是没问题的,要用三个五年计划甚至一个五年计划来实现,这种事情只有太祖和疯子敢做。