这是今天早上刚一上班,一个网友请教问题带出来的话题,个人感觉比较有普遍性,所以把QQ留言做了抄录,整理成一篇文章。

话题不大,不过,我想这里面体现出来的职业化程序员在进行Coding的时候所秉持的一些设计原则还是很有借鉴意义的,大家可以参考一下。

网友  9:39:17
class Memory: public NativeObject{
public:
      Memory();
      ~Memory();     
      void* malloc(long size);     
      Block* getBlock(long size); 
private:     
      Number* size;     
      Number* minisize;     
      Number* maxsize;     
      std::vector<Block*> blocks; 
};

肖舸  9:39:55

网友  9:40:06
我定义了一个这样的类,在构造函数阶段没有初始化blocks
我现在malloc函数里面对blocks进行初始化
怎么做啊
在构造函数上初始化,应该是Memory():blocks(){}
但是我不想让他在构造阶段初始化blocks

肖舸  9:45:03
你把block的初始化放在malloc就可以了

网友  9:46:43
void* Memory::malloc(long size) {
blocks = new blocks();
return NULL;
}
这样?

肖舸  9:46:56
可能不行
得有个bool量
如果已经初始化过了,就不要初始化了
if(!blocks) blocks=new blocks()

网友  9:48:15
您这个地方的blocks应该是一个指针吧
我在定义的时候定义的是std::vector<Block*> blocks;

肖舸  9:49:04
建议啊
我们对于类嵌套的成员对象,一般都是用指针
然后显式的在函数中去new
实做中几乎不会声明成员对象实体,因为会引发非常多的额外问题
我们习惯于自己控制一切,很少使用C++默认的构造和析构动作

网友  9:50:43
我也觉得我这样做,在析构函数里面的操作会比较纠结
谢谢肖老师了

肖舸  9:51:48
C++默认构造函数,其构造的时间点是不确定的
如果两个对象有依赖关系,而你平行地写出他们的对象声明
比如A依赖B,你声明:
    A a;
    B b;
则C++编译器编译后,哪个先执行是不确定的
如果A先执行,则由于B没有初始化,会崩溃
这种崩溃一般都找不到原因,因为这是编译器自己添加的代码,你看不到
VC++就有这个问题
体现在你写得好好的程序,可能某一次编译过后就永远崩溃,前面一直好好的。
而且找不到原因

网友  9:54:25
明白了
是我的用法有问题
那我再请教一个问题,我想给我自己定义的类标记一个唯一的字符串
希望能够通过字符串将我定义的类找到
并实例化对象
这个需要怎么做啊

肖舸  9:56:15
为什么要这么做?

网友  9:57:13
我尝试做一个可以在程序外部,进行简单配置来生成一些对象

肖舸  9:57:54
这是一个伪命题,虽然看起来很酷,你这涉及到运行期动态类查询的一个高阶应用,我年轻的时候也迷过一阵子,感觉很酷
但是,没有实用性,根据现代分布式计算理论,这个问题在实际中会有很多办法规避掉,起码我在实做中一次都没有用过
不需要这么做
C++单独解决这个问题有点麻烦,但是如果依赖dll或者so等操作系统资源来说,很容易,你去看看COM接口,那里面的动态查询和枚举,就是干这个事情的。
建议不要钻这个牛角尖,费力气很大,对于赚钱没帮助

网友  10:00:35
第四点也是我很纠结的问题
但是我技术力量不够的话,又谈何赚钱呢
所以我也不知道怎么权衡

肖舸  10:01:11
起码这点已经没用了
根据云计算、分布式服务器集群的理论,计算即服务,我们现在普遍的都在想办法把计算做成一个个独立的网络服务,而不是基于单机模型下面

网友  10:01:53
其实我是先慢慢尝试做一个OO

肖舸  10:02:00
想办法动态实例化对象,实现内置式计算
OO在未来模型中,需要有限使用,不要太深入
C++目前实用度并不高,建议多学一点C
C才是根本

肖舸  10:03:21
STL不要再看了,有害,你就算学会了,一到多线程环境,全部完蛋
STL是单线程的,没有多线程安全性

网友  10:03:54
我设计预期的OO也是单线程的
像js一样
其中有一个很酷的语法是
devices.[has(child) ? this : void]?.[*.contains(module)? void : module];

肖舸  10:04:16
现在哪还有单线程程序?
别酷了,你要真这么写,得哭了

网友  10:04:40
这样一句话就实现了两次循环

肖舸  10:04:51
如果写错了,怎么debug?

网友  10:04:51
节约了3到4个中间变量

肖舸  10:05:10
情愿多浪费计算机资源,不要浪费程序员的脑力
你绞尽脑汁节约了3~4个中间变量
大约节约了12~16Bytes
现在的计算机,内存起步就是2G,有意义吗?
反而,如果中间有一个隐蔽的bug,查错误可能要半个月
你半个月的工资能再买台计算机了

肖舸  10:06:47
做事情别太过于技术了,算算经济账,你就知道,多写几个变量,把程序多写几行,你好懂,别人也好懂,计算机也好懂,这个最值钱
就算别人来看你的代码,起码我看你这个代码,得费点脑筋,嗯,要花一上午吧
我一上午工资是多少?
是不是比16Bytes的内存值钱?

网友  10:07:52
可能是我想多了

肖舸  10:08:09
你不是想多了,是思路还限制在学院派里面
老想着写酷的代码,不想写赚钱的代码
酷代码往往成本高,风险大,一旦多了,迭代起来,出了问题找都找不到
最后的结果就是,大家公认你写的代码可能太高深了,都读不懂,质量也不咋地,无法合作
最后老板就只好请你走路了。
所以写程序久了,一般说来,都是越写越简单,最后都是大白话
我情愿写两个循环
甚至,我会拆分成两个函数,每个函数只有一个循环
这样看得明白啊
还有效率问题
你说到了循环,估计得循环查找是吧?

网友  10:10:46

肖舸  10:10:55
如果这个集合够大,比如几万个
你这么写,你怎么知道编译器内部使用什么算法来实现查找?
如果我来控制,我可以配搭两个Hash
一步到位实现高速检索

网友  10:11:27
这种循环方式肯定不是万金油啊

肖舸  10:11:35
这总比鬼都不知道什么算法的效率高吧
永远不要相信编译器
它不知道你的需求
把动作拆细,你就会发现很多优化要点

网友  10:12:46
你讲的很在理,我好好消化消化
在技术上,在赚钱上,都好好琢磨琢磨

肖舸  10:13:55
嗯,做商用化程序员是个大话题,你好好琢磨一下吧