试图理解“指向成员的指针”

尔比斯

我正在尝试了解“指向成员的指针”的工作原理,但并不是所有事情对我来说都是显而易见的。

这是一个示例类:

class T
{
public:
    int a;
    int b[10]; 
    void fun(){}
};

以下代码说明了问题并包含一些问题:

void fun(){};

void main()
{
   T obj;                
   int local;
   int arr[10];
   int arrArr[10][10];

   int *p = &local;   // "standard" pointer
   int T::*p = &T::a; // "pointer to member" + "T::" , that is clear

   void (*pF)() = fun;        //here also everything is clear
   void (T::*pF)() = T::fun;  
   //or
   void (T::*pF)() = &T::fun;  

   int *pA = arr; // ok
   int T::*pA = T::b; // error

   int (T::*pA)[10] = T::b; // error
   int (T::*pA)[10] = &T::b; //works;

//1. Why "&" is needed for "T::b" ? For "standard" pointer an array name is the representation of the 
//   address of the first element of the array. 

//2. Why "&" is not needed for the pointer to member function ? For "standard" pointer a function name 
//   is the representation of the function address, so we can write &funName or just funName when assigning to the pointer. 
//   That's rule works there.

//3. Why the above pointer declaration looks like the following pointer declaration ?: 

   int (*pAA)[10] = arrArr; // Here a pointer is set to the array of arrays not to the array. 
   system("pause");
}
亚伦·麦克戴德(Aaron McDaid)

我认为最简单的事情是暂时忘记类成员,然后回顾指针和衰减。

int local;
int array[10];

int *p = &local; // "standard" pointer to int

人们倾向于说“衰减的指针”与指向数组的指针相同。但是arr之间有一个重要的区别&arr前者不会衰退为后者

int (*p_array_standard)[10] = &arr;

如果这样做&arr,您将获得一个指向10整数数组的指针。这与指向9整数数组的指针不同。它与指向int的指针不同。sizeof(*p_array_standard) == 10 * sizeof(int)

如果你想有一个指针的第一个元素,即一个指针int,用sizeof(*p) == sizeof(int)),那么你可以这样做:

int *p_standard = &(arr[0);

到目前为止,所有内容都基于标准/显式指针。

在C中一个特殊的规则,它允许您更换&(arr[0])arr您可以int*&(arr[0])或用初始化一个arr但是,如果您实际上想要一个指向数组的指针,则必须int (*p_array_standard)[10] = &arr;

我认为这种衰变几乎可以被视为一种语法糖。衰减不会改变任何现有代码的含义。它只是允许否则将是非法的代码变为合法。

int *p = arr; // assigning a pointer with an array.  Why should that work?
                  // It works, but only because of a special dispensation.

当数组衰减时,它衰减为指向单个元素的指针int [10]-> int*它不会衰减到指向该数组的指针int (*p)[10]


现在,我们可以从您的问题来看这一行:

int (T::*pA3)[10] = T::b; // error

同样,班级成员与理解为什么失败无关。左侧的类型是整数的指针,而不是整数的指针。因此,正如我们之前所说,衰减不相关,您需要&获取指向整数数组的指针类型。

一个更好的问题是问为什么这不起作用(更新:我现在看到您的问题中确实有这个问题。

int T::*pA3 = T::b;

右侧看起来像一个数组,而左侧是指向单个元素的指针int *,因此您可以合理地问:为什么衰减在这里不起作用?

要理解为什么衰减很难在这里,让我们的“撤消”语法糖,并更换T::b&(T::b[0])

int T::*pA3 = &(T::b[0]);

我认为这是您感兴趣的问题。为了关注实际问题,我们已经删除了衰减问题。该行适用于非成员对象,为什么不适用于成员对象?

简单的答案是该标准不需要它。指针衰减是一种语法糖,他们只是没有指定它在这种情况下必须起作用。

指向成员的指针基本上比其他指针要容易。它们必须直接指向对象中出现的“原始”实体。对不起,我的意思是它应该(通过编码类的开头和该成员的位置之间的偏移量来间接地引用。但是我不太擅长对此进行解释。)它们不能指向子对象,例如数组的第一个元素,或者实际上是数组的第二个元素。

问:现在我有一个自己的问题。可以将指针衰减扩展到这样的成员数组上吗?我认为这是有道理的。 我不是唯一想到这一点的人!有关更多信息,请参见此讨论这是可能的,我想没有什么可以阻止编译器将其实现为扩展。子对象(包括数组成员)与类的开头有固定的偏移量,因此这很合逻辑。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

指向成员函数的指针

来自分类Dev

指向成员函数的指针

来自分类Dev

指向指针成员结构的指针

来自分类Dev

理解指向结构的指针是指访问它的 c 中的指针成员

来自分类Dev

指向功能成员的指针

来自分类Dev

指向数据成员的指针数组

来自分类Dev

指向成员函数的指针的向量

来自分类Dev

指向C ++中成员的指针

来自分类Dev

指向类的成员函数的指针

来自分类Dev

python中的“指向成员的指针”

来自分类Dev

指向托管班级成员的指针

来自分类Dev

下垂指向成员函数的指针

来自分类Dev

指向成员函数的函数指针

来自分类Dev

指向成员函数的指针-语法

来自分类Dev

指向类成员函数的指针

来自分类Dev

指向成员函数的函数指针

来自分类Dev

试图更好地理解指针

来自分类Dev

指向成员的指针所指向的函数类型

来自分类Dev

指向成员的指针所指向的函数类型

来自分类Dev

成员函数返回指向成员函数的指针

来自分类Dev

成员函数指向成员函数的指针

来自分类Dev

指向成员变量作为静态成员的指针

来自分类Dev

指向函数调用的指针与指向成员函数调用的指针

来自分类Dev

指向函数调用的指针与指向成员函数调用的指针

来自分类Dev

指向类模板成员的函数指针

来自分类Dev

指向成员表达式UB的指针

来自分类Dev

存储指向成员函数的指针的容器

来自分类Dev

指向类成员函数的函数指针

来自分类Dev

通过指向类成员的指针调用函数