C++ 访问班级成员

示例

要访问类对象的成员变量和成员函数,请使用.运算符:

struct SomeStruct {
  int a;
  int b;
  void foo() {}
};

SomeStruct var;
// 访问var中的成员变量a。
std::cout <<var.a<< std::endl;
// 在var中分配成员变量b。
var.b = 1;
// 调用成员函数。
var.foo();

通过指针访问类的成员时,->通常使用运算符。或者,可以取消引用实例并使用.运算符,尽管这种情况不太常见:

struct SomeStruct {
  int a;
  int b;
  void foo() {}
};

SomeStruct var;
SomeStruct *p = &var;
// 通过指针访问var中的成员变量a。
std::cout << p->a << std::endl;
std::cout << (*p).a << std::endl;
// 通过指针在var中分配成员变量b。
p->b = 1;
(*p).b = 1;
// 通过指针调用成员函数。
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;
// 在结构SomeStruct中分配静态成员变量c。
SomeStruct::c = 5;
// 通过var和p访问结构SomeStruct中的静态成员变量c。
var.a = var.c;
var.b = p->c;
// 调用静态成员函数。
SomeStruct::bar();
var.bar();
p->bar();

背景

->需要该运算符,因为成员访问运算符的.优先级高于解引用运算符*。

有人希望*p.a可以取消引用p(导致对该对象p所指向的引用),然后访问其成员a。但实际上,它尝试访问的成员a,p然后取消引用它。即*p.a相当于*(p.a)。在上面的示例中,由于两个事实,这将导致编译器错误:首先,p是一个指针,并且没有member a。第二,a是一个整数,因此不能被取消引用。

此问题的不常用解决方案是显式控制优先级: (*p).a

相反,->几乎总是使用运算符。它是先解引用指针然后访问它的快捷方式。即(*p).a与完全相同p->a。

该::运算符是作用域运算符,其使用方式与访问名称空间的成员相同。这是因为静态类成员被视为在该类的范围内,但不被视为该类实例的成员。出于历史原因,尽管静态成员不是实例成员,也可以使用normal.和->static成员;这用于在模板中编写通用代码,因为调用者不必担心给定的成员函数是静态的还是非静态的。