2

以下4种调用另一个成员函数的方式有什么区别?

是否有一个好处导致一种方法是可取的?

void Object::trigger() {
  (*this).triggerinner(10);
  this->triggerinner(10);
  triggerinner(10);
  Object::triggerinner(10);
}

void Object::triggerinner(int x) {
  std::cout << "trigger" << std::endl;
}
4

6 回答 6

4

前三个在非模板代码中基本相同。在模板成员函数中,前两个使名称查找依赖(因此编译器可以在依赖的基类中查找名称)。一般来说,越简单越好,所以大多数人喜欢第三种形式,除非需要依赖查找,在这种情况下他们会使用第二种。

第四种形式阻止虚拟分辨率。(实际上,它具有与上述相同的三种形式,即 this->Object::triggerinner(10)等。)当您想要强制解析时使用它:被调用的函数将 Object在 的基类中或中Object,但从不在派生类中,即使函数是虚函数。这最常用于派生类中,用于在执行其他工作之前(或之后)调用基类实现:

void
Derived::func()
{
    Base::func();
    //  Additional work here...
}

在成员函数之外,它还可以用于在没有对象时调用静态成员函数。

于 2013-10-23T08:10:31.237 回答
1

前两个是完全等价的。根据定义,(*p).thingp->thing​​等价于任何指针。

第三种在这种情况下是等价的;但如果成员函数的名称被局部声明隐藏,则可能具有不同的含义。还有一些情况(函数是基类的成员,并且涉及模板)当此表单找不到函数时,在这种情况下您将不得不使用其他函数之一。

如果函数不是虚拟的,则第四个是等价的。如果它是虚拟的,那么这将强制对此类中可用的覆盖进行非虚拟调用,而不是最终覆盖。

于 2013-10-23T08:07:53.070 回答
0

最常用的是this->triggerinner(10);。它使用指针与表进行简单匹配的原因。

于 2013-10-23T08:07:57.373 回答
0
(*this).triggerinner(10);

这很丑陋,“->”是为了避免这样做。

this->triggerinner(10);

这很好,但this->不是强制性的。如果您正在处理现有项目,请保持当前的编码风格。

triggerinner(10);

很好,与使用this->.

Object::triggerinner(10);

将此用于静态方法。

我建议您使用它,triggerinner(10)因为它简短明了。

于 2013-10-23T08:03:05.970 回答
-1

this->triggerinner(10)比其他人更好:

  1. (*this).triggerinner(10)因为它更具可读性更好。
  2. 比 更好triggerinner(10),因为在这种情况下,您将不知道triggerinner()是方法还是函数(然后具有不同的范围)。
  3. Better than Object::triggerinner(10)which 主要用于静态方法(但不仅如此)
于 2013-10-23T08:05:58.683 回答
-1

没有区别,除非你的编译器做了一些时髦的东西。尝试阅读由函数中的行生成的汇编语言,看看是否有任何差异,或者是否一遍又一遍地生成相同的指令块。

至于“最好的”或“最受欢迎的”,取决于您的个人喜好或在公司工作时,他们可能会强制执行某些编码标准,迫使您在每次做某事时都以特定的方式编写。

于 2013-10-23T08:06:41.793 回答