密闭C++算子 以下神秘的C++操作符的目的是什么?

密闭C++算子 以下神秘的C++操作符的目的是什么?,c++,operators,C++,Operators,指向成员的指针 ::* 按指针将指针绑定到成员 ->* 通过引用将指针绑定到成员 .* 指向成员的指针允许您拥有一个相对于特定类的指针 假设你有一个联系人类,有多个电话号码 class contact { phonenumber office; phonenumber home; phonenumber cell; }; 这个想法是,如果你有一个算法需要使用一个电话号码,但决定哪一个电话号码应该在算法之外执行,那么指向成员解决问题的指针: void robo

指向成员的指针

::*
按指针将指针绑定到成员

->*
通过引用将指针绑定到成员

.*

指向成员的指针允许您拥有一个相对于特定类的指针

假设你有一个联系人类,有多个电话号码

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
或:


看看这本书。搜索您正在谈论的特定运算符在大多数浏览器中,Ctrl-F会打开一个查找/搜索对话框,允许您搜索网页中的文本,这将有助于您更好地理解问题。

一个过于简单的答案-这些运算符允许将成员函数作为“常规”函数调用,至少从最终用户的角度来看是一样的。现实世界的例子——它们在各种回调实现中被大量使用

没有像::*这样的操作符,而且从来没有。我不知道你从哪里弄来的

至于->*和。*-这些是指针指向成员类型指针的解引用运算符


至于指向成员的指针是什么。。。你最喜欢的C++书在这个主题上说了什么?

允许你有指向与该类的一个特定实例绑定的成员函数和成员变量的指针。

指向成员函数的指针对于诸如状态模式的轻量级实现之类的事情很有用。一般来说,任何时候想要改变对象的行为,而不需要切换整个对象,可以考虑使用指向成员函数的指针。

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.
}

如果您想(例如)实现一种通用算法,在结构数组中搜索给定字段具有特定值的条目,则可以使用指向成员变量的指针。

它们与指向成员的指针和指向成员函数的指针相关

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.
}
虽然它看起来像一个,但它不是一个操作符。是::运算符和*运算符类型修饰符相邻。要证明这一点而不必阅读标准,请尝试添加空格::*编译,*没有,也没有->*

至于它们的实际用途——与函数指针的原理相同。您不会像我上面所说的那样使用它们,在这种情况下,您可以按名称调用函数,但可以将它们作为参数传递,或者从函数返回、存储它们,或者根据复杂的逻辑从几个函数中选择一个


如果有帮助的话,我相信语法的选择是这样的,尽管。*是一个不可分割的单个运算符,但您可以想象*dm表示c,dm指向的成员。因此,如果dm指向c,那么f.*dm与f.c.是一样的。

不管维基百科怎么说,::*不是运算符。我从维基百科中得到::*作为我问题的参考:::*在g++中编译得很好。@Neil g:到底什么在g++中编译得很好?@Neil g:::是运算符,因为标准这么说,因为::标记在C++的语法中扮演着操作符的角色:*不是操作符,因为当它列出操作符时,标准不提及它,并且因为C++被解析时没有::*令牌。int x=5+-2;编译,并不意味着+-是运算符。@Neil G:首先,在Samuel的回答中没有::*运算符。你能找到的唯一地方是::*他的答案和我的一样是声明。声明中没有运算符这类东西,即使某些东西看起来像运算符。当你看到int i=1;在代码中,=位不是运算符,它只是一个声明的语法元素。InformIT on上有一个可读的指南。这里有一个很好的例子:是的,指向成员的指针非常方便-我广泛使用它们来序列化字节流和数据库结果集。有点像穷人的倒影。使用成员指针字段和方法,您可以轻松地设置数据结构,允许在静态知识很少的情况下对类型进行动态操作,这通常有助于获得公共基础和一些访问者风格的分派方法。
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.
}