c++ - 试图了解 "pointer to member"

标签 c++

我试图了解“指向成员的指针”是如何工作的,但对我来说并非一切都清楚。

这是一个示例类:

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");
}

最佳答案

Why "&" is needed for "T::b" ?

因为标准需要它。这是为了区别于访问静态类成员。

来自标准草案 n3337,第 5.3.1/4 段,强调我的:

A pointer to member is only formed when an explicit & is used and its operand is a qualified-id not enclosed in parentheses. [Note: that is, the expression &(qualified-id), where the qualified-id is enclosed in parentheses, does not form an expression of type “pointer to member.” Neither does qualified-id, because there is no implicit conversion from a qualified-id for a non-static member function to the type “pointer to member function” as there is from an lvalue of function type to the type “pointer to function” (4.3). Nor is &unqualified-id a pointer to member, even within the scope of the unqualified-id’s class. — end note]


For "standard" pointer an array name is the representation of the address of the first element of the array.

不是真的。如果需要,数组会自动转换 为指向第一个元素的指针。数组的名字是一个数组,句点。


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.

这里同样适用于数组。有一个自动转换,否则一个函数有一个函数类型。

考虑:

#include <iostream>

template<typename T, size_t N>
void foo(T (&)[N]) { std::cout << "array\n"; }

template<typename T>
void foo(T*) { std::cout << "pointer\n"; }

int main()
{
    int a[5];
    foo(a);
}

输出为数组

函数指针也是如此:

#include <iostream>

template<typename T>
struct X;

template<typename T, typename U>
struct X<T(U)> {
    void foo() { std::cout << "function\n"; }
};

template<typename T, typename U>
struct X<T(*)(U)> {
    void foo() { std::cout << "function pointer\n"; }
};

void bar(int) {}

int main()
{
    X<decltype(bar)> x;
    x.foo();
}

输出是函数


关于这一点的澄清,因为我不确定你的评论到底想表达什么:

int arrArr[10][10];
int (*pAA)[10] = arrArr; // Here a pointer is set to the array of arrays not to the array.

同样,数组到指针的转换。请注意,arrArr 的元素是 int[10]pAA 指向 arrArr 的第一个元素,这是一个包含 10 个整数的数组,位于 &arrArr[0]。如果您增加 pAA,它将等于 &arrArr[1](因此将其命名为 pA 会更合适)。

如果你想要一个指向整个arrArr的指针,你需要说:

int (*pAA)[10][10] = &arrArr;

递增 pAA 现在会让您刚好超过 arrArr 的末尾,即 100 个整数。

关于c++ - 试图了解 "pointer to member",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25833449/

相关文章:

c++ - 如何用 C++ 编写 'pass reference by value' 包装器?

c++ - 关于foreach循环和性能的几个问题

c++ - 在 C++ 中删除指针 vector 与对象

java - 如何在 invokeshutdown 方法中获取 jobject

c++ - C++ 中的常量函数

c++ - OpenGL:缓冲到 VBO 后我还需要一个顶点数组吗?

c++ - 如何优化 curl 库的大小?

c++ - 如何覆盖 unordered_map 的 [] 运算符

iphone - 如何停止 Objective C 中的函数递归?

C++11 数组初始化不会调用复制构造函数