我试图了解“指向成员的指针”是如何工作的,但对我来说并非一切都清楚。
这是一个示例类:
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 doesqualified-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/