xiaobailong 发表于 2005-6-1 20:43

楼上这段东东编译通不过的。gaga那段既然编译通过了,又能执行,和你这个还是有本质区别的。


不过gaga那段,如果让我做code review,那也是通不过的。就算代码不重写,至少文档要写得详细一些才行。没办法,高手也不能由着性子来,得照顾到我们这些低手的理解能力。。。。对不?

gaga 发表于 2005-6-2 13:07

//问题的实质是如何调用class member形式的function pointer。下面的例子把自定义函数简化了。
//假设有一堆函数 f1(x), f2(x), f3(x),想计算一组采样点的sum,用OOP的话自然而然写成一个class:
class CBasisFunction
{
private:
int m_nType;

typedef double (CBasisFunction::*PFUNCTION)(double);

double f1(double x) { return x; }
double f2(double x) { return x*x; }
double f3(double x) { return 1/x; }

public:
PFUNCTION pBF;

CBasisFunction(void){
    m_nType = 0;
};
void SetBasisFunction (int nType) {
    m_nType = nType;
    switch(m_nType){
    case 0:
      pBF = &CBasisFunction::f1;
      break;
    case 1:
      pBF = &CBasisFunction::f2;
      break;
    case 2:
      pBF = &CBasisFunction::f3;
      break;
    }
}
};


//使用这个类的时候,代码只能写成
#include <stdio.h>
int main()
{
CBasisFunction BF;
double x, sum=0;
BF.SetBasisFunction(1);
for (x=0; x<1; x+=0.01){
    sum+=(BF.*BF.pBF)(x);      //调用类成员形式的函数指针
}
printf("%lf\n", sum);
return 0;
}


// OOP的目标是让代码容易理解和维护,可这里却让人费解。不知道有没有更好的方法?
// 写完这个类和积分算法类(梯形、simpson)后就再也没有维护过,反正用起来省事。。。
// 积分类的调用也比较夸张
// CBasisFunction BF;
// CIntegrateImpl<CBasisFunction> *itg = new CIntegrateImpl<CBasisFunction>(&BF, BF.pBF);
// BF.SetBasisFunction(1);
// itg->Integrate(a,b);

gaga 发表于 2005-6-2 13:12

constructor 少了行 pBF = NULL;

xiaobailong 发表于 2005-6-2 19:55

代码结构挺清楚的,很好。   看懂了个大概。

执行了 BF.SetBasisFunction(1); 之后,BF.pBF就应该指向函数f2了吧。但为什么调用的时候是 (BF.*BF.pBF)(x);         而不是直接 (BF.pBF)(x)呢?

xiaobailong 发表于 2005-6-2 19:58

Originally posted by gaga at 2005-6-2 14:12
constructor 少了行 pBF = NULL;


这句倒是看懂了。:lol:
;)

gaga 发表于 2005-6-2 20:23

Originally posted by xiaobailong at 2005-6-2 20:55
代码结构挺清楚的,很好。   看懂了个大概。

执行了 BF.SetBasisFunction(1); 之后,BF.pBF就应该指向函数f2了吧。但为什么调用的时候是 (BF.*BF.pBF)(x);         而不是直接 (BF.pBF)(x)呢?


编译会产生错误
语法函数指针的访问应该是 (*p)()
而成员函数指针因为作用域的问题不能直接用*访问
所以我在这里用 BF.*BF.pBF来访问

我也不知道是不是只能这么做,有高手来琢磨琢磨吗?

xiaobailong 发表于 2005-6-2 21:23

我也没用过,不过 pBF是public的吧? BF.pBF就是f2了, (*BF.pBF)()相当于前面提到的(*p)(), 也就是f2(),

哎呀,明白了,f2是BF的私有函数,所以前面必须加 BF., 合起来就是(BF.*BF.pBF)(x)了。

高手啊,真高手。

当真code review的时候,一定要把这段说明加到文档里才行。不然一下子转不过这么多弯来。

gaga 发表于 2005-6-2 22:17

Originally posted by xiaobailong at 2005-6-2 22:23
呀,明白了,f2是BF的私有函数,所以前面必须加 BF., 合起来就是(BF.*BF.pBF)(x)了。


不是因为私有函数的问题,即便f1,f2,f3都是pubilc的也不能直接用*去执行函数。

代码写成这样其实应该算失败,只是暂时没有想到其他的办法。
编程(指写代码这块)这东西说起来没有高手之说,只有熟练度和风格。
那些奇怪的技巧除了增加维护难度,意义并不是很大了。
那些“看不懂程序大赛”的作品,恐怕永远也不会被一个正式的工程采纳吧

xiaobailong 发表于 2005-6-2 22:40

“看不懂程序大赛”, 哈哈。

f2是class CBasisFunction的成员函数,BF是其实例,函数调用是BF.f2(). 这样说总对了吧。

程序写的精简,其实有时候也是很需要的,所以才会有code review和文档说明这两回事呀。您老就不要谦虚了。 (中国人的美德之一?)是不是有人夸你不习惯?向我学习吧,我就最喜欢有人夸我,没别人夸的时候还自夸一下。例如solaris安装的帖子上了google搜索的第一页之类的。只要是真的,就可以夸。还有lidragon,硬件高手,被夸的时候也是当仁不让。

另外,论坛上灌水也不用太认真吧?

gaga 发表于 2005-6-2 23:52

http://www.de.ioccc.org/main.html

就是这个IOCCC,以前有次尝试去读他们的作品,读了半天除了茫然还是茫然,挫折感极大 ==
页: 1 [2] 3
查看完整版本: 作孽,居然写出这样的代码……