如果我有一个具有虚函数且没有自由函数的类,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()
答案 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()
。一些存在差异的例子是:
A
的块范围声明,则A()
将调用声明的函数,而this->A()
将始终调用成员函数。请参阅http://coliru.stacked-crooked.com/a/ea49916562bd4371 A
是从属基类的成员,则尝试将其称为A()
将失败; this->A()
需要将名称查找推迟到实例化时间。答案 2 :(得分:0)
关于Non-static member functions的Cppreference声明模板定义的上下文存在差异:
在X的非静态成员函数体内,任何 解析为非类型的id-expression E(例如标识符) X的非静态成员或X的基类转换为a 成员访问表达式(* this).E(除非它已经是a的一部分 成员访问表达式)。这在模板定义中不会发生 上下文,所以名称可能必须以此为前缀 - >明确地 变得依赖。
因此,在您的示例中,它没有任何区别,但在其他情况下,例如在定义模板时,它可以。