从对象本身访问成员或成员范围
Accessing members from an object itself with either THIS or member scope
访问该类别类的成员数据/功能的正确方法是什么?似乎有3个含义:
class test{
private:
int variable;
public:
void setVariable(int value) {
variable = value; // method 1, using the variable name directly
this->variable = value; // method 2, via pointer dereference of 'this'
test::variable = value; // method 3, via scope operator
}
};
他们似乎都在工作。他们等效吗?除了样式/一致性外,是否有理由使用另一个?
除了您提到的样式和一致性,有时您还必须使用特定的语法来消除歧义。
"方法2"可以用来消除本地变量和类成员之间的歧义。
"方法3"可以用来在类层次结构的不同位置的同名字段之间消除歧义。
通常,它无关紧要,因此更简单的选项member = value;
是首选。在某些情况下,局部变量可能会有歧义,您可以在那里符合this->
前缀的资格,但是更好的方法是完全避免歧义。
然而,在某些角案件中确实很重要。处理虚拟函数时,使用合格的名称(type::member
)禁用运行时调度并确保type
级别的最终超级层被调用:
struct base {
virtual int f() { return 1; }
};
struct derived : base {
virtual int f() { return 2; }
void g() {
std::cout << f() << "n";
std::cout << derived::f() << "n";
}
};
struct mostderived : derived {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3 2
}
处理模板类和继承时,查找分为两个阶段。在第一阶段,必须解决非依赖性名称。不合格的名称是一个非依赖性名称,因此在某些情况下,您需要使用this->
或type::
的资格,并且上述区别仍然适用。额外的资格用于使名称取决于:
template <typename T>
struct derived : T {
void g() {
// std::cout << f() << "n"; // Error, cannot resolve f() [*]
this->f(); // Ok, pick final overrider at runtime
derived::f(); // Ok, pick overrider here: base::f()
}
};
struct base {
virtual int f() { return 1; }
};
struct mostderived : derived<base> {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3, 1
}
对于对象内的代码,通常没有区别,因此通常只使用variable = value;
并使用它是最干净的。
有时在模板中,您可能会遇到一个仅使用变量名称的情况,而this->variable
消除了这种歧义 - 但这很少足够this->everything
定期仅仅是因为它可能会偶尔有用。
- 方法1:这是完成的常见方式。
- 方法2 :这是做到这一点的最佳和最一致性的方法。很清楚阅读和理解正在发生的事情。
- 方法3:我从未在现实世界代码中见过。
作为侧面注释:使用方法1 时,如果与函数参数发生命名冲突,并且成员变量将在成员变量上使用函数参数。
如果我们有:
void setVariable(int variable) {
variable = variable; // method 1, this does not change the member variable.
this->variable = variable; // method 2, via pointer dereference of 'this'
test::variable = variable; // method 3, via scope operator
}
指针通常用于类的超载运算符。它的用途之一可以是,如果函数中传递的参数与对象本身相同,例如:
class CDummy {
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this) return true;
else return false;
}
此也用于将指针返回到对象本身
ClassEx ClassEx::Func(//params)
{
//code
return *this;
}
按照正常的比较,value
而不是this->value
的使用效率更高,除非您检查值,否则this->
的使用是模棱两可的。
性能没有差异。::
用于避免歧义,例如,当您具有具有相同名称的本地变量时,或在派生类中声明字段相同名称的字段。支持->
是因为this
的类型是指向对象的指针,因此编译器必须接受this->something
,并且也可以用于避免歧义或只是让代码更加清晰。
,并添加到上述答案中:某些代码样式喜欢使用固定前缀(例如_
或m
)识别成员变量。使用"方法2"是在代码中实现这一清晰度的另一种(并且更好的方法)。
优于this->value
而不是value
,也有点像使用std::cin
代替cin
与using namespace std
。
使用方法1
variable = value;
节省您如此频繁购买新键盘!
(说我应该停止在我的咖啡上维咖啡!)
- 重载运算符的范围是什么?它是否会影响作为类成员的集合的插入函数?
- 迭代嵌套映射与范围为循环:没有名为"first"的成员
- 检查私有成员变量是否在一定范围内,如果没有调整
- 立即传递其成员时的右值范围
- 成员变量在超出BeginPlay函数虚幻引擎的范围时丢失值c++
- 越界成员函数定义是否需要一个完全限定的类名,直到全局范围
- 对象超出范围后,引用成员设置为 0
- pImpl、范围和隐藏数据成员
- 在命名成员函数重载解析期间,"this"何时不在范围内?
- 当在另一个范围中,将SelfAdjointeigensolver保存为成员的结果被重新引入
- 成员的结构与命名空间的潜在范围
- C++奇怪的问题.数据成员超出范围
- 范围视图作为数据成员
- 基于循环的C ISTRINGSTREAM范围没有开始成员
- 为 具有"end"成员变量的类型启用基于范围的
- 如何将成员函数引入范围
- 如何基于每个成员覆盖类范围的__declspec(dllexport)注释?
- 从对象本身访问成员或成员范围
- c++单元测试:改变成员范围
- 在不更改成员范围的情况下有条件地启用静态成员