语法this-> func()和func()之间是否存在细微差别?

时间:2017-01-12 23:30:57

标签: c++ virtual-functions

如果我有一个具有虚函数且没有自由函数的类,this->func()func()

之间是否有任何差异
class Base {
    virtual void A() { std::cout << "Base" << std::endl; };
    void B() { this->A(); };
    void C() { A(); };
};

class Derived : public Base {
    virtual void A() { std::cout << "Derived" << std::endl; };
    void B2() { this->A(); };
    void C2() { A(); };
};

方法B()C()的执行是否有任何差异?方法B2()C2()

怎么样?

3 个答案:

答案 0 :(得分:7)

在您发布的示例中,两种语法之间没有区别。它们完全相同。

有两种情况存在差异。一种是如果你有一个模板类,它继承自依赖于模板参数的类型。例如:

CharactersGroup

这里,由于public abstract class CharactersGroup<C extends Character> { private ArrayList<C> characters; public CharactersGroup() { this(new ArrayList<C>()); } public CharactersGroup(ArrayList<C> list) { characters = list; } } 继承自类型public class HeroesGroup extends CharactersGroup<Hero> { public HeroesGroup() { this(new ArrayList<Hero>()); } public HeroesGroup(ArrayList<Hero> list) { super(list); } } ,这取决于模板参数,因此名称查找是在两步过程中完成的。如果您使用非限定语法调用template <typename T> class Base { public: void doSomething() const { std::cout << "Do ALL the things!" << std::endl; } }; template <typename T> class Derived: public Base<T> { public: void doSomethingElse() const { doSomething(); // Error! this->doSomething(); // Okay } }; ,则编译器不知道调查Derived<T>以找到它并报告错误。但是,如果您说Base<T>,它就知道您正在调用成员函数,并最终会发现它应该查看doSomething

如果在函数内声明了一个本地对象,其名称与成员函数相同,则会出现另一种情况。例如:

Base<T>

第二种情况非常罕见,以至于我从未见过它,而且我甚至可以说它的编码风格很差。

除了这些罕见的情况之外,在使用和不使用this->doSomething()作为前缀的情况下调用自己的成员函数之间没有区别。

答案 1 :(得分:3)

通常没有区别,因为标准要求A()形式的成员函数调用等同于(*this).A()。一些存在差异的例子是:

  1. 如果存在A的块范围声明,则A()将调用声明的函数,而this->A()将始终调用成员函数。请参阅http://coliru.stacked-crooked.com/a/ea49916562bd4371
  2. 如果A是从属基类的成员,则尝试将其称为A()将失败; this->A()需要将名称查找推迟到实例化时间。

答案 2 :(得分:0)

关于Non-static member functions的Cppreference声明模板定义的上下文存在差异:

  

在X的非静态成员函数体内,任何   解析为非类型的id-expression E(例如标识符)   X的非静态成员或X的基类转换为a   成员访问表达式(* this).E(除非它已经是a的一部分   成员访问表达式)。这在模板定义中不会发生   上下文,所以名称可能必须以此为前缀 - >明确地   变得依赖。

因此,在您的示例中,它没有任何区别,但在其他情况下,例如在定义模板时,它可以。