this->func() 和 func() 的语法之间有什么细微差别吗?

Are there any nuance differences between the syntax this->func() and func()?

如果我的 class 有虚函数,没有自由函数,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() 方法呢?

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

有两种情况是有区别的。一种是如果您有一个模板 class 继承自依赖于模板参数的类型。例如:

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> 类型,它依赖于模板参数,名称查找在 two-step 过程中完成。如果您使用非限定语法调用 doSomething,那么编译器将不知道查看 Base<T> 来找到它,并将报告错误。但是,如果你说 this->doSomething(),它知道你正在调用一个成员函数,并且最终会弄清楚它应该在 Base<T>.

中查找

另一种情况是在函数内部声明了一个与成员函数同名的局部对象。例如:

class ThisIsSillyDontDoThisLikeSeriouslyDont {
public:
    void doSomething() const {
        std::cout << "Do ALL the things!" << std::endl;
    }

    void weirdFunction() const {
        auto doSomething = [] {
            std::cout << "I'm afraid there's nothing to be done" << std::endl;
        };

        doSomething();       // Calls the local function
        this->doSomething(); // Calls the member function
    }
};

第二种情况非常罕见,我从未见过,我什至可以说它的编码风格非常糟糕。

不过,除了这些罕见的情况,使用和不使用 this-> 作为前缀调用自己的成员函数没有区别。

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

  1. 如果A有block-scope声明,那么A()会调用声明的函数,而this->A()会一直调用成员函数。参见 http://coliru.stacked-crooked.com/a/ea49916562bd4371
  2. 如果 A 是依赖基 class 的成员,那么尝试将其称为 A() 将失败; this->A() 需要将名称查找推迟到实例化时间。

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

Within the body of a non-static member function of X, any id-expression E (e.g. an identifier) that resolves to a non-type non-static member of X or of a base class of X, is transformed to a member access expression (*this).E (unless it's already a part of a member access expression). This does not occur in template definition context, so a name may have to be prefixed with this-> explicitly to become dependent.

所以在你的例子中它没有什么不同,但在其他情况下,例如定义模板时,可能会。