我何时应该使用this-> functionname()而不是classname :: functionname()来调用成员函数?

时间:2016-07-25 09:01:39

标签: c++ oop namespaces this

我一直在查看一些示例代码,它使用this->functionname()classname::functionname()来调用同一个类中的函数。

这两种方法之间确实存在差异吗?

此外,这些方法之间是否有区别,只需使用 functionname() 调用该函数?

感谢。

3 个答案:

答案 0 :(得分:4)

与C ++一样,事情并不像你想象的那么简单。

有三种方法可以调用成员函数。

  1. 只需调用函数:foo();
  2. 致电thisthis->foo();
  3. 使用班级名称:classname::f();
  4. 数字#1和#2是等价的,有些人更喜欢#2,因为它更清楚,这是一个成员函数,而不是一个全局函数(这些人是少数)。

    #3与#1和#2的区别是否取决于被调用的函数是否为虚函数。如果它是非虚拟的,则没有区别。如果虚拟,那么这个函数的派生覆盖更多,那么#1和#2将调用派生函数,#3将调用存在的覆盖在这个类中(或者如果这个类中没有覆盖,则是最接近的超类)。

    上一段的例外是当调用站点位于构造函数或析构函数中时。在这种情况下,即使函数是虚拟#1而#2的行为与#3相同(在此调用覆盖,或者最近的超类)。

    此外,如果函数为static,则#2无效,#1和#3在类中调用时是等效的,但从类外调用时需要#3。

    我希望我没有错过任何东西:)

    我错过的东西:

      如果函数被调用函数内部重新声明的全局隐藏,则可能需要
    • this。见@Dutow's answer
    • 在处理two phase lookup时(当涉及模板时),
    • this会很有用。感谢@Alejandro的评论。
    • 我猜测使用using可能会在水中投入更多的泥泞,但此刻我无法深入研究(警告经纪人)。

    确实,并不像人们想象的那么简单......

答案 1 :(得分:3)

一般?他们是一样的。但根据具体情况,它们可能意味着不同的东西。

例如,请考虑以下极端示例(不要在实际项目中执行此操作!):<​​/ p>

void f() { std::cout << "f" << std::endl; }

class Cl {
public:
    void f() { std::cout << "Cl::f" << std::endl;  }
    void g() { 
        struct Cl {
            static void f() { std::cout << "inside Cl::f" << std::endl; }
        };
        void f();  

        f(); 
        Cl::f();
        this->f();
    }
};

int main()
{
    Cl a;
    a.g();

    return 0;

}

在此,全局f声明会影响成员方法f,导致程序输出f而不是Cl::f

本地struct Cl也会影响其自己的类型名称,从而导致Cl::f()调用它的静态f方法。

仅显示调用this->f()会导致调用Cl::f

当您想在使用继承和覆盖虚拟方法时调用父类中的方法时,通常也会使用带有typename的变体 - 但这在技术上并不是同一个类。

答案 2 :(得分:1)

我认为使用此功能的一个原因是在这种情况下。 E.g。

class A
{
public:
    void foo() { this->doFoo(); } //equivalent to just doFoo();
    void foo2() { Abstract::doFoo(); }
private:
    virtual void doFoo() { /* do stuff */ }
};

在调用foo的代码段中,它将在派生程度最高的类中调用doFoo。当调用foo2时,即使它被覆盖,它也总是会调用基本实现。