对八荣八耻第6条的置疑

对八荣八耻第6条的质疑一切都是从这个帖子开始的http://bbs.csdn.net/topics/390335372然后,我在百度输入

对八荣八耻第6条的质疑
一切都是从这个帖子开始的
http://bbs.csdn.net/topics/390335372
然后,我在百度输入这个帖子的标题,又看到了一位大神这样的言论




--http://blog.sina.com.cn/s/blog_51abf7f8010096f6.html
由于对此博客部分言论存在怀疑,所以做一下验证:

[解决办法]
楼主你觉得设计模式很强大么?
[解决办法]
引用:
引用:这个是python的八荣八耻,那个帖子的楼主明显没搞清楚

但是这位明显是c++程序员
http://bbs.csdn.net/topics/390335372



所以说他没搞清楚,以缩进为例,也只有python会把缩进放在这么重要的位置,并特别指出,因为它本身就是语法的一部分,
同样,高级脚本语言的无休止的动态动态动态,且一切皆对象的思维,让多态更有意义。
不应当以c++为参照,讨论那个八荣八耻。
[解决办法]

[解决办法]
尺有所短,寸有所长。
凡事无绝对,荣耻互转化。
过去叫“厚颜无耻”,现在叫“心理素质过硬”!
对八荣八耻第6条的置疑
[解决办法]
对八荣八耻第6条的置疑
学习,汇编角度看问题
[解决办法]
3,毫无扩展性而言。当有新的策略加进来的时候,只能增加一个策略处理函数或者某块,再在if语句下增加if-else的分支。后续的改动会使得已经确认的代码被修改,并且代码凌乱得使人抓狂。与敏捷软件设计的原则背离。

光是这一点就足够改为其他的方式实现了。

效率的差异根本不是理由
多态的形式,至少有1次访问指针()、一次跳转操作(),这2个操作是编译器无法优化的。 访问指针、跳转都可能会造成高速缓存失效的问题,消耗的时间远大于比较操作。
但switch是可以优化的,就2#的代码,lz可以编译出release版再看看,测试一下消耗的时间。
[解决办法]
楼主贴的帖子所说的也未免太偏激了点
尺有所短,寸有所长
每一种paradigms都有适合使用的时机
不是任何问题都适合用多态解决

另外一种解法,配合template和functor
不但不需要承受virtual的开销
连switch,if...else的开销都免了

template<typename Strategy>
void resolve(Strategy strategy)
{
  strategy();
}

class strategy2
{
public:
  void operator()()
  {
    std::cout<<"str two"<<std::endl;
  }
};

int main() //tmain不被标准支援,main被标准支援
{
   resolve([](){std::cout<<"str one"<<std::endl;});
   resolve(strategy2());   

   return 0;
}


缺点是可能会产生code bloat的问题
相对的也有可能产生更快,更小的代码
另外一个好处是不必用到继承,耦合度低的多
这其实就是stl算法的设计手段
模组化的好帮手

再来一种,利用std::function的解法
这解法的效率较低,但是弹性很高

void resolve(std::function<void()> func)
{
  func();
}

void output()
{
  std::cout<<"strategy 1"<<std::endl;
}

class strategy3
{
  public:
    void exectue()
    {
      std::cout<<"strategy 3"<<std::endl;
    }
};

int main()
{
  resolve(output);
  resolve([](){std::cout<<"s2";});
  
  auto str = [](){std::cout<<"s3";};
  resolve(str);

  resolve(std::bind(&strategy3::execute, strategy3()));
  return 0;
}

[解决办法]
更正,不是多态,是virtual
毕竟编译期间的多态也是多态的一种
各有优劣,在c++中编译期的多态尤其重要
[解决办法]
有时候教条主义害死人,有时后在修改别人代码时,发现可能只是一个小的功能模块,非要强制使用一些设计模式,用的也是一知半解,还不如不用,放点注释都比这个好。
[解决办法]
引用:
有时候教条主义害死人,有时后在修改别人代码时,发现可能只是一个小的功能模块,非要强制使用一些设计模式,用的也是一知半解,还不如不用,放点注释都比这个好。



同意,想当初学院派都喜欢说GOTO语句不能用,这个其实很误导人,不能因为有个高人提出GOTO语句有危害,然后就都说不好,我就觉得非常好用。
[解决办法]
还是要看具体的应用环境来论证,如果说是必须反复执行的一系列分支,那自然是分支要比接口效率高些,但有些时候不是必须反复执行的分支,如果用接口事先绑定,其执行效率就比分支高了。
[解决办法]

[解决办法]
凡是不要绝对,
接口本身没问题,但过多的对象创建反而降低效率
[解决办法]
。。。不是吧?我觉得这些模式,都是为了一个“开闭原则”,这根本就不是比效率。说分支效率就比多态低,这纯属扯淡。
[解决办法]
引用:
引用:多态当然比分支效率高。抛开前面的细节不说,光说多态,它在编译创建对象时就确定了唯一调用的处理函数,分支结构要通过比较从一系列处理函数中找到合适的那个。
一个相当于直接寻址,一个相当于查找。
使用多态的原因不会是因为它的效率会比分支高,分支本质是比较操作,而使用多态的时候,比较操作是不可少的,此外还有许多额外动作。既然使用高级特……

多态真没有比较。就是两次到三次无条件跳转。
[解决办法]
设计模式真的很强大啊,虽然代码多了,但是维护,拓展,修改都变的easy了,效率只是一个方面的原因,但不是唯一原因。
举个简单的例子,QQ版本那么多,但是却可以相互通信不受影响,如果加判断,那么多版本switch-case语句得有多长啊,但是比如用责任链模式,就变得简单方便易拓展了,拓展就添加高版本的类,而且不用修改什么代码。这就是多态比if..else好的一个小地方。
[解决办法]
毛主席说过“实践是查验真理的唯一标准”,对我们来说也貌似有用,动手检验一下就知道了,呵呵。
[解决办法]
引用:
关于第一种,我不太明白,模版参数只是在编译期起作用啊?当然,其实好多分支判断都是没必要的,可优化的,这些分支都可以用模版转移到编译期的。
C/C++ code?1234567……


是的,第一种是利用编译期间的多态进行绑定,所以执行效率比virtual和if..else都来得更高

引用
但是,模版到现在我都不敢在写个人库的时候把它加到里面,因为以前被那些奇怪的链接错误整怕了

纯模板库会出现链接错误我到现在还没遇过,因为模板的实现和宣告一般都会放在同一个header里面
估计你遇上的是其他错误?

引用
编译成dll和lib是不是有什么不方便的地方?

我没试过将模板库编译成dll和lib,大部分的c++ compiler都不能将template的实现和接口分离
我个人会使用的方法一般上是这样的
一 : 需要用到模板的地方写在另外一个header里
二 : 想导出dll或lib的函数或class,在.cpp档里面使用模板库实现

另外一个方法是对某个type进行explicit的instantiation
只把你需要的type弄成dll和lib,不过这方法我没试过

说实话,模板库要弄成dll或lib还挺麻烦的
一般都是直接写在同一个header里面

引用
请问写模版版本的函数库的时候在接口声明和实现的编码上要注意什么?

要写清楚这个库要遵守什么concept
目前的标准因为还不支援concept,会比较麻烦

其实只要把primer 5的第16章弄懂
对template的了解就足够应付日常编程了
不要被那些template wizard吓到
我们就算不能把template用得跟他们一样出神入化
也不会对日常的编程造成什么影响
[解决办法]
比较复杂的template库的除错讯息很难懂
static_assert可以多加利用,让除错讯息好读一点

以下是比较进阶一点的

看看modern c++ design的policy based design
这个设计方法在某些情况下可以产生很大的威力

多读读stl各类算法的实现,不但可以提升对算法的了解
也可以学到template库的其中一种设计方法

善用c++11的<type_traits>,这东西可以简繁琐的化metaprogramming
将性能榨得更干净

最后的重点,除非程式必要写得复杂,否则尽量让自己的程式简单一点
[解决办法]


[解决办法]
饭吃多了也会撑死,任何事物都有个度,否则物极必反。
[解决办法]

引用:
引用:引用:引用:多态当然比分支效率高。抛开前面的细节不说,光说多态,它在编译创建对象时就确定了唯一调用的处理函数,分支结构要通过比较从一系列处理函数中找到合适的那个。
一个相当于直接寻址,一个相当于查找。
使用多态的原因不会是因为它的效率会比分支高,……

debug也没有分支的。
你如果想说RTTI的话,这个并不是直接和多态有关。使用多态不一定要RTTI的。
[解决办法]
引用:
引用:引用:引用:引用:引用:多态当然比分支效率高。抛开前面的细节不说,光说多态,它在编译创建对象时就确定了唯一调用的处理函数,分支结构要通过比较从一系列处理函数中找到合适的……

函数名本身是vtable里一个常数偏移。只要vptr有了,调用起来就是调用*(vptr[k])()而已。不需要cmp。
RTTI有cmp很正常。但是让虚函数中枪我就蚵蚵了。
[解决办法]
 如果
   if() {}
   else{}
太底的效率
不能用了!

那么:
   编程语言就不要提供这个功能了。

//
我看上面的教条很是反对,
  其实就是反对异已而已!

就好象,猴子取笑人没长尾巴;


[解决办法]
引用:
一切都是从这个帖子开始的
http://bbs.csdn.net/topics/390335372
然后,我在百度输入这个帖子的标题,又看到了一位大神这样的言论

C/C++ code?12345    在程序的控制中,经常会有在某种条件下使用某种策略的问题,也有在某种条件下使用某一组参数的问题。对于这些控制,我在学校的时候经常采用if-else、switch等分……


楼主分析的很不错。
或许那个人说的不是机器的运行效率,而是程序员编程维护的效率
[解决办法]
分支多了会降低开发效率吧,严重降低。
但是多态多了,一个是降低运行效率,更严重的是会降低维护效率——到处多态,非debug不能确定程序的分支究竟如何运行。