我一直在查看一些示例代码,它使用this->functionname()
和classname::functionname()
来调用同一个类中的函数。
这两种方法之间确实存在差异吗?
此外,这些方法之间是否有区别,只需使用 functionname()
调用该函数?
感谢。
答案 0 :(得分:4)
与C ++一样,事情并不像你想象的那么简单。
有三种方法可以调用成员函数。
foo();
this
:this->foo();
classname::f();
数字#1和#2是等价的,有些人更喜欢#2,因为它更清楚,这是一个成员函数,而不是一个全局函数(这些人是少数)。
#3与#1和#2的区别是否取决于被调用的函数是否为虚函数。如果它是非虚拟的,则没有区别。如果是虚拟和,那么这个函数的派生覆盖更多,那么#1和#2将调用派生函数,#3将调用存在的覆盖在这个类中(或者如果这个类中没有覆盖,则是最接近的超类)。
上一段的例外是当调用站点位于构造函数或析构函数中时。在这种情况下,即使函数是虚拟#1而#2的行为与#3相同(在此调用覆盖,或者最近的超类)。
此外,如果函数为static
,则#2无效,#1和#3在类中调用时是等效的,但从类外调用时需要#3。
我希望我没有错过任何东西:)
我错过的东西:
this
。见@Dutow's answer。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
时,即使它被覆盖,它也总是会调用基本实现。