訪問類成員
要訪問類物件的成員變數和成員函式,請使用 .
運算子:
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
完全相同。
::
運算子是作用域運算子,其使用方式與訪問名稱空間成員的方式相同。這是因為靜態類成員被認為是在該類的範圍內,但不被視為該類的例項的成員。由於歷史原因,靜態成員也允許使用普通的 .
和 ->
,儘管他們不是例項成員; 這用於在模板中編寫通用程式碼,因為呼叫者不需要關心給定的成員函式是靜態的還是非靜態的。