【发布时间】:2010-05-10 22:01:54
【问题描述】:
【问题讨论】:
-
无论维基百科怎么说,
::*不是操作员。
【问题讨论】:
::* 不是操作员。
指向成员的指针允许您拥有一个相对于特定类的指针。
所以,假设您有一个包含多个电话号码的联系人类。
class contact
{
phonenumber office;
phonenumber home;
phonenumber cell;
};
这个想法是,如果你有一个算法需要使用电话号码,但应该在算法之外决定哪个电话号码,指向成员的指针解决了问题:
void robocall(phonenumber contact::*number, ...);
现在robocall的呼叫者可以决定使用哪种类型的电话号码:
robocall(&contact::home, ...); // call home numbers
robocall(&contact::office, ...); // call office number
.* 和 ->* 一旦有了指针就会发挥作用。所以在robocall里面,你会这样做:
contact c = ...;
c.*number; // gets the appropriate phone number of the object
或:
contact *pc = ...;
pc->*number;
【讨论】:
没有像::* 这样的运算符,而且从来没有。我不知道你从哪里弄来的。
至于->* 和.* - 这些是pointer-to-member 类型指针的取消引用运算符。
struct S {
int i;
};
int main() {
int S::*pi = &S::i; // pointer of pointer-to-member type
S s;
S* ps = &s;
s.*pi = 0; // operator `.*` used
assert(s.i == 0);
ps->*pi = 1; // operator `->*` used
assert(s.i == 1);
}
至于指向成员的指针是什么……你最喜欢的 C++ 书籍在这个主题上是怎么说的?
【讨论】:
:: 是一个运算符,因为标准是这样说的,并且因为 :: 标记在 C++ 语法中扮演运算符的角色。 ::* 不是运算符,因为标准在列出运算符时没有提及它,并且因为在解析 C++ 时没有 ::* 标记。 int x = 5+-2; 编译,并不意味着+- 是一个操作符。
::* 运算符。您可以找到::* 的唯一地方是他的答案(以及我的答案)是声明。声明中没有“运算符”之类的东西,即使某些东西可能看起来像运算符。当您在代码中看到int i = 1; 时,= 位不是运算符,它只是声明的句法元素。
它们与指向成员的指针和指向成员函数的指针有关。
struct Foo {
int a() { return 1; }
int b() { return 2; }
int c;
};
int main() {
Foo f;
f.c = 3;
typedef int (Foo::*member_fn)(); // pointer-to-member-function
typedef int (Foo::*data_member); // pointer-to-member
member_fn mf = &Foo::a;
(f.*mf)(); // calls the member function pointed to by mf. returns 1
mf = &Foo::b;
(f.*mf)(); // This time, returns 2, since mf points to b
Foo *fp = &f;
(fp->*mf)(); // same thing, via pointer to f instead of object/reference f.
data_member dm = &Foo::c;
f.*dm; // is 3
f.*dm = 5;
f.c; // is now 5.
Foo f2; // another instance
f2.c = 12;
f2.*dm; // is 12. Same pointer-to-member, different object.
}
虽然看起来像一个,::* 不是运算符。它是:: 运算符和* operator 类型修饰符并排在一起。为了证明这一点而不求助于阅读标准,请尝试添加空格::: * 编译,. * 没有,-> * 也没有。
至于它们的实际用途——与函数指针的原理相同。你不会像我上面那样使用它们,在这种情况下你可以只按名称调用函数,但你可以将它们作为参数传递或从函数中返回、存储它们,或者根据复杂的逻辑选择几个之一。
如果有帮助,我相信选择了这样的语法,尽管.* 是一个不可分割的单个运算符,但您可以想象*dm“意味着”c,即 dm 指向的成员。所以如果dm指向c,那么f.*dm和f.c是一样的。
【讨论】:
查看C++ FAQ Lite's section on pointers to member functions。搜索您正在谈论的特定“运算符”(在大多数浏览器中,Ctrl-F 打开一个查找/搜索对话框,允许您在网页中搜索文本),它应该可以帮助您更好地理解事物。
【讨论】:
一个过于简单的答案 - 这些运算符允许将成员函数称为“常规”函数(至少从最终用户的角度来看是一样的)。现实世界的例子——它们在各种回调实现中被大量使用。
【讨论】:
这些允许您拥有指向绑定到类的特定实例的成员函数(和成员变量)的指针。
指向成员函数的指针对于状态模式的轻量级实现非常有用。一般来说,任何时候你想随着时间的推移改变一个对象的行为而不求助于切换整个对象,你可以考虑使用指向成员函数的指针。
如果您想要,可以使用指向成员变量的指针,例如,实现一个通用算法来搜索结构数组以查找具有给定字段的特定值的条目。
【讨论】: