方法和自由函数之间的细微差别是什么?

时间:2011-12-08 18:17:32

标签: c++ function methods implementation

据我了解,方法实际上只是带有隐式额外参数(this指针)的函数,而静态方法与自由函数几乎相同。

但方法和功能之间似乎存在一些差异;例如,当将函数作为参数传递时,为什么必须在方法上使用引用运算符&,而不是在自由函数上使用?

foobar(&MyClass::method);
goobar(freefunction);

方法和自由函数之间还有哪些微妙的技术差异?

2 个答案:

答案 0 :(得分:3)

在:

foobar(&MyClass::method);

... &不是“参考运算符”,而是地址运算符。它采用其操作数的地址。

你实际上仍然“必须”在代码中获取自由函数的地址(尽管隐式转换可用):

goobar(freefunction);

有可用的隐式转换会导致Foo这样的表达式衰减到指针,但是我很难让GCC接受这样的代码错误 - 并且没有警告,在这种情况下MSVC没有问题。

除此之外,自由函数和非静态成员函数之间存在两个主要区别:

  1. static成员函数对类的实例进行操作,并且有一个this指针指向类本身。
  2. 通过指向自由函数的指针创建和调用的语法与指向成员函数的指针的语法不同。
  3. 在自由函数的情况下,语法是微不足道的(ish):

    void foo();  // Function declaration
    void(*f)();  // Declaration of pointer-to-function-returning-void-and-taking-no-parameters
    

    但是在指向成员函数的指针的情况下,语法要复杂得多:

    struct Bar
    {
      void DoIt()
      {
      }
      void DoThat(int n)
      {
        n;
      }
    };
    
    
    void(Bar::*thatfn)(int);    // declares a pointer-to-member-function taking int returning nothing
    thatfn = &Bar::DoThat;      // initializes pointer to point to DoThat(int)
    (bar.*thatfn)(42);          // call the function
    

答案 1 :(得分:1)

我认为这是因为(§5.3.1/ 3)所说的,

  

指向成员的指针仅在显式&使用它的操作数是一个未括在括号中的限定id。

然后它继续解释为:

  

[注意:表达式&(qualified-id),其中qualified-id括在括号中,不形成“指向成员的指针”类型的表达式。也不是qualified-id,因为那里不是从非静态成员函数的qualified-id到类型“指向成员函数的指针”的隐式转换,因为从函数类型的左值到类型“指向函数的指针”(4.3)。即使在unqualified-id类的范围内,也不是& nonqualified-id指向成员的指针。 ]


我刚刚讨论了两个有趣的话题,尤其是@Johannes的回答是一个很好的解读:

还有这个:

这也意味着这个话题应该接近投票,因为它似乎是重复的。