这是一个事实,您可以使用以下语法显式访问成员变量(在成员函数内,而不是特别是构造函数):this->member_name
(即区分具有相同名称的函数参数)。
除此之外,我认为语法ClassName::static_member
被保留用于访问类外的静态成员。
当我意识到以下set_2()
方法正如人们期望的那样工作时,我感到很惊讶:
#include <iostream>
struct A {
int x;
// The two following methods seem to act similarly:
void set_1(int x) { this->x = x; }
void set_2(int x) { A::x = x; }
};
int main ()
{
A a;
a.set_1(13);
std::cout << a.x << std::endl;
a.set_2(17);
std::cout << a.x << std::endl;
return 0;
}
在这种情况下,使用范围运算符(A::x
)是一种好的有效做法吗?我个人更喜欢它,而不是使用this->x
语法。
答案 0 :(得分:3)
在这种情况下使用A::x
是有效的,但我认为this->x
更惯用且更不容易出错(代码的读者可以立即看到x
是其成员这个班,不考虑A
是什么。)
答案 1 :(得分:2)
根据C ++标准(3.3.7类范围)
2类成员的名称只能按如下方式使用:
- 在其类的范围内(如上所述)或派生的类 (第10条)来自其班级,
- 之后。运算符应用于其类型的表达式 class(5.2.5)或从其类派生的类
- 在 - &gt;之后运算符应用于指向其类对象的指针 (5.2.5)或从其类中派生的类
- 将:: scope resolution运算符(5.1)应用于名称之后 它的类或派生自其类的类。
例如,派生类的方法的数据成员可以隐藏其基类的数据成员和/或方法。要访问基类的数据成员和方法,可以使用范围解析运算符。
struct Base
{
virtual ~Base() {};
virtual void Hello() const { std::cout << "Base" << std::endl; }
};
struct Derived : Base
{
virtual void Hello() const
{
Base::Hello();
std::cout << "and Derived" << std::endl;
}
};
Derived d;
d.Hello();
答案 2 :(得分:0)
在您的情况下,A::x
仍然是指您的常规成员变量;它只是明确指定你的意思是 x
。考虑一个派生自另外两个具有相同名称成员的类的类(不是那种非常好的编码风格):
struct A { int x; };
struct B { int x; };
struct C : A, B
{
int foo() const
{
// return x; // ambiguous: which x do you mean?
return A::x; // unambiguous
}
};