访问类成员
要访问类对象的成员变量和成员函数,请使用 .
运算符:
struct SomeStruct {
int a;
int b;
void foo() {}
};
SomeStruct var;
// Accessing member variable a in var.
std::cout << var.a << std::endl;
// Assigning member variable b in var.
var.b = 1;
// Calling a member function.
var.foo();
通过指针访问类的成员时,通常使用 ->
运算符。或者,可以取消引用实例并使用 .
运算符,尽管这种情况不太常见:
struct SomeStruct {
int a;
int b;
void foo() {}
};
SomeStruct var;
SomeStruct *p = &var;
// Accessing member variable a in var via pointer.
std::cout << p->a << std::endl;
std::cout << (*p).a << std::endl;
// Assigning member variable b in var via pointer.
p->b = 1;
(*p).b = 1;
// Calling a member function via a pointer.
p->foo();
(*p).foo();
访问静态类成员时,使用::
运算符,但是使用类的名称而不是它的实例。或者,可以使用 .
或 ->
运算符分别从实例或指向实例的指针访问静态成员,其语法与访问非静态成员的语法相同。
struct SomeStruct {
int a;
int b;
void foo() {}
static int c;
static void bar() {}
};
int SomeStruct::c;
SomeStruct var;
SomeStruct* p = &var;
// Assigning static member variable c in struct SomeStruct.
SomeStruct::c = 5;
// Accessing static member variable c in struct SomeStruct, through var and p.
var.a = var.c;
var.b = p->c;
// Calling a static member function.
SomeStruct::bar();
var.bar();
p->bar();
背景
->
运算符是必需的,因为成员访问运算符 .
优先于解除引用运算符*
。
人们会期望*p.a
会取消引用 p
(导致对 p
指向的对象的引用),然后访问其成员 a
。但事实上,它试图访问 p
的成员 a
,然后取消引用它。即*p.a
相当于*(p.a)
。在上面的示例中,由于两个事实,这将导致编译器错误:首先,p
是一个指针,并且没有成员 a
。其次,a
是一个整数,因此不能被解除引用。
对这个问题不常见的解决方案是明确控制优先级:(*p).a
相反,->
运算符几乎总是被使用。它是第一个取消引用指针然后访问它的简写。即 (*p).a
与 p->a
完全相同。
::
运算符是作用域运算符,其使用方式与访问命名空间成员的方式相同。这是因为静态类成员被认为是在该类的范围内,但不被视为该类的实例的成员。由于历史原因,静态成员也允许使用普通的 .
和 ->
,尽管他们不是实例成员; 这用于在模板中编写通用代码,因为调用者不需要关心给定的成员函数是静态的还是非静态的。