当前位置: 首页 > 编程笔记 >

详解C++中的成员访问运算符和指针到成员运算符

席乐童
2023-03-14
本文向大家介绍详解C++中的成员访问运算符和指针到成员运算符,包括了详解C++中的成员访问运算符和指针到成员运算符的使用技巧和注意事项,需要的朋友参考一下

成员访问运算符:. 和 ->

语法

      postfix-expression
      . name
postfix-expression –> name
备注
成员访问运算符 . 和 -> 用来引用结构、联合和类的成员。成员访问表达式具有选定成员的值和类型。
有两种形式的成员访问表达式:
在第一种形式中,postfix-expression 表示结构、类或联合类型的值,name 为指定的结构、联合或类的成员命名。运算的值是 name 的值且为左值(如果 postfix-expression 是左值)。
在第二种形式中,postfix-expression 表示指向结构、联合或类的指针,name 为指定的结构、联合或类的成员命名。该值是 name 的值且是左值。 –> 运算符取消引用该指针。因此,表达式 e–>member 和 (*e).member(其中,e 表示指针)会产生相同的结果(重载运算符 –> 或 * 的情况除外)。
以下示例演示成员访问运算符的两种形式。

// expre_Selection_Operator.cpp
// compile with: /EHsc
#include <iostream>
using namespace std;

struct Date {
  Date(int i, int j, int k) : day(i), month(j), year(k){}
  int month;
  int day;
  int year;
};

int main() {
  Date mydate(1,1,1900);
  mydate.month = 2;  
  cout << mydate.month << "/" << mydate.day
     << "/" << mydate.year << endl;

  Date *mydate2 = new Date(1,1,2000);
  mydate2->month = 2;
  cout << mydate2->month << "/" << mydate2->day
     << "/" << mydate2->year << endl;
  delete mydate2;
}

这样的话出来的两个值分别为:

2/1/1900
2/1/2000

指针到成员运算符:.* 和 ->*

 
语法

      expression .* expression
expression –>* expression
备注
指向成员的指针运算符(.* 和 –>*)返回表达式左侧上指定的对象的特定类成员的值。右侧必须指定该类的成员。下面的示例演示如何使用这些运算符:

// expre_Expressions_with_Pointer_Member_Operators.cpp
// compile with: /EHsc
#include <iostream>

using namespace std;

class Testpm {
public:
  void m_func1() { cout << "m_func1\n"; }
  int m_num;
};

// Define derived types pmfn and pmd.
// These types are pointers to members m_func1() and
// m_num, respectively.
void (Testpm::*pmfn)() = &Testpm::m_func1;
int Testpm::*pmd = &Testpm::m_num;

int main() {
  Testpm ATestpm;
  Testpm *pTestpm = new Testpm;

// Access the member function
  (ATestpm.*pmfn)();
  (pTestpm->*pmfn)();  // Parentheses required since * binds
            // less tightly than the function call.

// Access the member data
  ATestpm.*pmd = 1;
  pTestpm->*pmd = 2;

  cout << ATestpm.*pmd << endl
     << pTestpm->*pmd << endl;
  delete pTestpm;
}
Output
m_func1
m_func1

结果分别为:

1
2

在前面的示例中,指向成员的指针 pmfn 用于调用成员函数 m_func1。另一个指向成员的指针 pmd 用于访问 m_num 成员。
二元运算符 .* 将其第一操作数(必须是类类型的对象)与其第二操作数(必须是指向成员的指针类型)组合在一起。
二元运算符 –>* 将其第一操作数(必须是指向类类型的对象的指针)与其第二操作数(必须是指向成员的指针类型)组合在一起。
在包含 .* 运算符的表达式中,第一操作数必须是类类型且可访问,而指向第二操作数中指定的成员的指针或可访问类型的成员的指针明确从该类派生并且可供该类访问。
在包含 –>* 运算符的表达方式中,第一操作数必须是第二操作数中指定的类型的“指向类类型的指针”或明确地从该类派生的类型。
考虑以下类和程序段:

// expre_Expressions_with_Pointer_Member_Operators2.cpp
// C2440 expected
class BaseClass {
public:
  BaseClass(); // Base class constructor.
  void Func1();
};

// Declare a pointer to member function Func1.
void (BaseClass::*pmfnFunc1)() = &BaseClass::Func1;

class Derived : public BaseClass {
public:
  Derived(); // Derived class constructor.
  void Func2();
};

// Declare a pointer to member function Func2.
void (Derived::*pmfnFunc2)() = &Derived::Func2;

int main() {
  BaseClass ABase;
  Derived ADerived;

  (ABase.*pmfnFunc1)();  // OK: defined for BaseClass.
  (ABase.*pmfnFunc2)();  // Error: cannot use base class to
              // access pointers to members of
              // derived classes. 

  (ADerived.*pmfnFunc1)();  // OK: Derived is unambiguously
               // derived from BaseClass. 
  (ADerived.*pmfnFunc2)();  // OK: defined for Derived.
}

指向成员的指针运算符 .* 或 –>* 的结果是在指向成员的指针的声明中指定的类型的对象或函数。因此,在前面的示例中,表达式 ADerived.*pmfnFunc1() 的结果是指向返回 void 的函数的指针。如果第二操作数是左值,则此结果为左值。
System_CAPS_note注意
如果某个指向成员的指针运算符的结果是函数,则该结果只能用作函数调用运算符的操作数。

 类似资料:
  • C++ 运算符 .(点)运算符和 ->(箭头)运算符用于引用类、结构和共用体的成员。 点运算符应用于实际的对象。箭头运算符与一个指向对象的指针一起使用。例如,假设有下面的结构: struct Employee { char first_name[16]; int age; } emp; (.)点运算符 下面的代码把值 "zara" 赋给对象 emp 的 first_name 成员:

  • C++ 重载运算符和重载函数 类成员访问运算符( -> )可以被重载,但它较为麻烦。它被定义用于为一个类赋予"指针"行为。运算符 -> 必须是一个成员函数。如果使用了 -> 运算符,返回类型必须是指针或者是类的对象。 运算符 -> 通常与指针引用运算符 * 结合使用,用于实现"智能指针"的功能。这些指针是行为与正常指针相似的对象,唯一不同的是,当您通过指针访问对象时,它们会执行其他的任务。比如,当

  • C++ 运算符 C++ 提供了两种指针运算符,一种是取地址运算符 &,一种是间接寻址运算符 *。 指针是一个包含了另一个变量地址的变量,您可以把一个包含了另一个变量地址的变量说成是"指向"另一个变量。变量可以是任意的数据类型,包括对象、结构或者指针。 取地址运算符 & & 是一元运算符,返回操作数的内存地址。例如,如果 var 是一个整型变量,则 &var 是它的地址。该运算符与其他一元运算符具有

  • 本文向大家介绍详解C++中的函数调用和下标以及成员访问运算符的重载,包括了详解C++中的函数调用和下标以及成员访问运算符的重载的使用技巧和注意事项,需要的朋友参考一下 函数调用 使用括号调用的函数调用运算符是二元运算符。 语法 备注 在此上下文中,primary-expression 为第一个操作数,并且 expression-list(可能为参数的空列表)为第二个操作数。函数调用运算符用于需要大

  • 本文向大家介绍C++中的四个默认成员函数与运算符重载详解,包括了C++中的四个默认成员函数与运算符重载详解的使用技巧和注意事项,需要的朋友参考一下 本文主要给大家介绍了关于C++默认成员函数与运算符重载的相关内容,分享出来公的敬爱啊参考学习,话不多说,来一起看看详细的介绍: 一:类和对象的基础知识:类的定义,访问限定符,面向对象封装性,对象的大小计算等等。(编译环境为VS2015) 面向对象程序设

  • 以下SSCCE说明了这种情况: 项目之前编译得很好,我用几个编译器(、、、和)再次检查了这个SSCCE,所有这些编译器都在没有任何警告的情况下编译了它(使用)。所有编译器都设置为C++11/C++0x标准。将ctor添加到中后,即使在和上也能很好地编译 使两个的非成员都显示了所有编译器中的二义性(正如预期的那样) 在查看了标准草案(和)之后,我没有找到任何使成员函数/运算符比非成员函数/运算符更匹

  • 我正在构建一个关于有理数的C++项目。我已经定义了一个名为RationalNumber的类,它包含了构造函数和算术(+,-,*,/)运算符、关系(<,>,<=,>=)运算符和相等(==,!=)运算符的重载,还有>>运算符。我有两个私有属性:分子和分母(整数)。现在,我有个问题!为了返回两个RationalNumber对象中较大的指针,可以重新重载operator>?如果是,我该怎么做? 我就这样试

  • 本文向大家介绍详解C++中new运算符和delete运算符的使用,包括了详解C++中new运算符和delete运算符的使用的使用技巧和注意事项,需要的朋友参考一下 C++ 支持使用 new 和 delete 运算符动态分配和释放对象。这些运算符为来自称为“自由存储”的池中的对象分配内存。 new 运算符调用特殊函数 operator new,delete 运算符调用特殊函数 operator de