2011-08-12 56 views
1

我有一个对象,它有一个数学函数。它似乎是operator()的完美人选。运算符()在C++

具体来说,它是一种光线,它对球体上的每个(phi,theta)位置都有不同的值。

现在的事情是,当类中,访问灯功能有这个crunky语法:

 
    double operator() (double phi, double theta) 
    { 
     // compute light function 
     return sin(2*t) * cos(p) ; // (really this is implemented as a function pointer, 
            // so the light function can be changed) 
    } 

    void functionThatUsesLightFunction() 
    { 
     
         
 
          
  double val = (2.0, 4.0) ; // seems bad
         
  // Whoops! Doesn't work. 
     double val2 = (*this)(2.0, 4.0) ; // ok 
     double val3 = operator()(2.0, 4.0) ; // no thank you 
    } 

但是从类外,它得到这个非常好的语法像

 
    foreach(theta on 0..PI) 
     foreach(phi on 0..2*PI) 
      val += light(theta, phi) ; 

你认为我在这里误用了operator()吗?

+3

你不能定义一个(private?)方法'compute(bla)'并在'operator()'中调用它吗?然后你可以在类内调用'compute'并在外面使用'operator()'。 –

+4

第一种机制不会调用'operator()'。 –

+0

我不是'operator()'的粉丝。 Operator()是一个没有名字的方法:这是皇帝的新方法(就像皇帝的新衣服一样)。 'operator()'看起来就像从外面裸露的一样,看起来和内部一样丑陋。这里完全穿衣的功能有什么问题,例如“照明”? –

回答

5

我认为你应该在类的私有部分定义另一个函数calculate,并从operator()和其他成员函数中调用此函数。这样,你不会从成员函数中调用operator(),但是你仍然可以在课堂外调用它。财产以后这样的:

class Light 
{ 
    private: 
    double calculateLight(double phi, double theta) 
    { 
     return sin(2*t) * cos(p) ; 
    } 
    public: 
    double operator() (double phi, double theta) 
    {  
     return calculateLight(phi, theta); 
    } 
    //... 
    void functionThatUsesLightFunction() 
    { 
     double val3 = calculateLight(2.0, 4.0); 
    } 
}; 

//Outside the class 
Light light; 
//... 
val += light(theta, phi) ; 

也有在添加calculateLight功能,您可以选择此功能,这增加了可读性好名字很好的优势。 operator()没有增加可读性。

+0

我不建议出于简单的原因避免重复,可读性和可维护性都受到影响。稍后有人会决定增加/改变operator()的功能,他们忘记了calculate()实际上是一个同义词。 '(* this)()'或'operator()()'没有任何错误或困难,它们非常易读,并且完全没有负担。 –

+2

@Gene:重复在哪里? –

+0

重复是,如果有人过来并将'operator()'改为:'return calculateLight(phi,theta)* 2;'。然后'functionThatUsesLightFunction'会做一些不同于'operator()'的东西,当它们应该使用相同的代码时。 – thelsdj

1

我不明白你为什么会在这里使用operator()。您不访问operator()正文中的任何对象字段,也无法更改对象状态。我宁愿创建一个静态方法或只是一个常规功能...

+1

这实际上充当了一个函数对象。 OP说,实际上,operator()会通过函数指针调用函数,函数指针可能是一个成员变量。这听起来像是一个非常合理的使用'operator()'。 –

+0

@Oli Charlesworth:从OP的角度来看,你绝对是对的,但我不认为这是必须应用OP方法的情况。例如,'sin'只是一个函数,而不是'operator class'用'operator()(double val)'...... – a1ex07

+0

@ a1ex07:但是就像Oli说的那样,看到提问者的评论,“这真的是作为一个功能指针,所以灯功能可以改变“。实际上'operator()'*确实*访问数据成员。所以你需要解释一个自由函数应该如何替换这个成员函数,它的输出取决于对象的当前状态。 –

0

YourClass::operator()a.operator() (arguments)而不是a(arguments)是非常好的。这只是一个习惯的问题。使用它一段时间,再加上C++风格的演员阵容,它会让你感觉更迂腐,之后你不会再为它烦恼。

+0

我不想感到迂腐!我想要漂亮的代码! – bobobobo

+0

然后使用Haskell :)。但是不要觉得有效的C++很丑陋。 – foxx1337