Yes, I've seen this question and
this FAQ (wrong link)
this FAQ, but I still don't understand what ->*
and .*
mean in C++.
Those pages provide information about the operators (such as overloading), but don't seem to explain well what they are.
是的,我看过这个问题和这个FAQ(错误链接),但是我还是不明白什么->*和。*在c++中的意思。这些页面提供了有关操作符的信息(例如重载),但似乎不能很好地解释它们是什么。
What are ->*
and .*
in C++, and when do you need to use them as compared to ->
and .
?
在c++中,->*和。*是什么?与->和。
6 个解决方案
#1
54
I hope this example will clear things for you
我希望这个例子能让你们明白
//we have a class
struct X
{
void f() {}
void g() {}
};
typedef void (X::*pointer)();
//ok, let's take a pointer and assign f to it.
pointer somePointer = &X::f;
//now I want to call somePointer. But for that, I need an object
X x;
//now I call the member function on x like this
(x.*somePointer)(); //will call x.f()
//now, suppose x is not an object but a pointer to object
X* px = new X;
//I want to call the memfun pointer on px. I use ->*
(px ->* somePointer)(); //will call px->f();
Now, you can't use x.somePointer()
, or px->somePointer()
because there is no such member in class X. For that the special member function pointer call syntax is used... just try a few examples yourself ,you'll get used to it
现在,您不能使用X. somePointer()或px->somePointer(),因为类x中没有这样的成员。你自己试试几个例子,你就会习惯的。
#2
18
EDIT: By the way, it gets weird for virtual member functions pointers.
编辑:顺便说一下,虚拟成员函数指针会变得很奇怪。
For member variables:
成员变量:
struct Foo {
int a;
int b;
};
int main ()
{
Foo foo;
int (Foo :: * ptr);
ptr = & Foo :: a;
foo .*ptr = 123; // foo.a = 123;
ptr = & Foo :: b;
foo .*ptr = 234; // foo.b = 234;
}
Member functions are almost the same.
成员函数几乎是一样的。
struct Foo {
int a ();
int b ();
};
int main ()
{
Foo foo;
int (Foo :: * ptr) ();
ptr = & Foo :: a;
(foo .*ptr) (); // foo.a ();
ptr = & Foo :: b;
(foo .*ptr) (); // foo.b ();
}
#3
10
In a nutshell: You use ->
and .
if you know what member you want to access. And you use ->*
and .*
if you don't know what member you want to access.
简而言之:您使用->和。如果您知道要访问哪个成员。如果您不知道要访问的成员,则使用->*和.*。
Example with a simple intrusive list
一个简单的插入列表的例子
template<typename ItemType>
struct List {
List(ItemType *head, ItemType * ItemType::*nextMemPointer)
:m_head(head), m_nextMemPointer(nextMemPointer) { }
void addHead(ItemType *item) {
(item ->* m_nextMemPointer) = m_head;
m_head = item;
}
private:
ItemType *m_head;
// this stores the member pointer denoting the
// "next" pointer of an item
ItemType * ItemType::*m_nextMemPointer;
};
#4
6
So called "pointers" to members in C++ are more like offsets, internally. You need both such a member "pointer", and an object, to reference the member in the object. But member "pointers" are used with pointer syntax, hence the name.
在c++中,所谓的“指针”更像是内部的偏移量。您需要这样的成员“指针”和对象来引用对象中的成员。但是成员“指针”与指针语法一起使用,因此命名。
There are two ways you can have an object at hand: you have a reference to the object, or you have a pointer to the object.
有两种方法可以将对象放在手边:对对象有引用,或者有指向对象的指针。
For the reference, use .*
to combine it with a member pointer, and for the pointer, use ->*
to combine it with a member pointer.
对于引用,使用.*将其与成员指针合并,对于指针,使用->*将其与成员指针合并。
However, as a rule, don't use member pointers if you can avoid it.
但是,作为一个规则,如果可以避免,不要使用成员指针。
They obey pretty counter-intuitive rules, and they make it possible to circumvent protected
access without any explicit casting, that is, inadvertently…
它们遵循相当反直觉的规则,而且它们使绕过受保护访问而不进行任何显式强制转换成为可能,也就是说,无意中……
Cheers & hth.,
欢呼声& hth。
#5
5
When you have a normal pointer (to an object or a basic type), you would use *
to dereference it:
当您有一个普通指针(指向对象或基本类型)时,您将使用*来取消它:
int a;
int* b = a;
*b = 5; // we use *b to dereference b, to access the thing it points to
Conceptually, we're doing the same thing with a member function pointer:
概念上,我们对一个成员函数指针做同样的事情:
class SomeClass
{
public: void func() {}
};
// typedefs make function pointers much easier.
// this is a pointer to a member function of SomeClass, which takes no parameters and returns void
typedef void (SomeClass::*memfunc)();
memfunc myPointer = &SomeClass::func;
SomeClass foo;
// to call func(), we could do:
foo.func();
// to call func() using our pointer, we need to dereference the pointer:
foo.*myPointer();
// this is conceptually just: foo . *myPointer ();
// likewise with a pointer to the object itself:
SomeClass* p = new SomeClass;
// normal call func()
p->func();
// calling func() by dereferencing our pointer:
p->*myPointer();
// this is conceptually just: p -> *myPointer ();
I hope that helps explain the concept. We're effectively dereferencing our pointer to the member function. It's a little more complicated than that -- it's not an absolute pointer to a function in memory, but just an offset, which is applied to foo
or p
above. But conceptually, we're dereferencing it, much like we would dereference a normal object pointer.
我希望这有助于解释这个概念。我们实际上取消了指向成员函数的指针。它比这复杂一点——它不是内存中函数的绝对指针,而是一个偏移量,它被应用到foo或p上面。但从概念上讲,我们是去引用它,就像我们要去引用一个普通的对象指针一样。
#6
4
You cannot dereference pointer to members as normal pointers — because member functions require this
pointer, and you have to pass it somehow. So, you need to use these two operators, with object on one side, and pointer on another, e.g. (object.*ptr)()
.
不能将成员指针作为普通指针来取消引用——因为成员函数需要这个指针,并且必须以某种方式传递它。因此,您需要使用这两个操作符,一边是对象,另一边是指针,例如(object.*ptr)()。
Consider using function
and bind
(std::
or boost::
, depending on whether you write C++03 or 0x) instead of those, though.
考虑使用函数和bind (std::或boost::,取决于您是编写c++ 03还是0x),而不是这些。
#1
54
I hope this example will clear things for you
我希望这个例子能让你们明白
//we have a class
struct X
{
void f() {}
void g() {}
};
typedef void (X::*pointer)();
//ok, let's take a pointer and assign f to it.
pointer somePointer = &X::f;
//now I want to call somePointer. But for that, I need an object
X x;
//now I call the member function on x like this
(x.*somePointer)(); //will call x.f()
//now, suppose x is not an object but a pointer to object
X* px = new X;
//I want to call the memfun pointer on px. I use ->*
(px ->* somePointer)(); //will call px->f();
Now, you can't use x.somePointer()
, or px->somePointer()
because there is no such member in class X. For that the special member function pointer call syntax is used... just try a few examples yourself ,you'll get used to it
现在,您不能使用X. somePointer()或px->somePointer(),因为类x中没有这样的成员。你自己试试几个例子,你就会习惯的。
#2
18
EDIT: By the way, it gets weird for virtual member functions pointers.
编辑:顺便说一下,虚拟成员函数指针会变得很奇怪。
For member variables:
成员变量:
struct Foo {
int a;
int b;
};
int main ()
{
Foo foo;
int (Foo :: * ptr);
ptr = & Foo :: a;
foo .*ptr = 123; // foo.a = 123;
ptr = & Foo :: b;
foo .*ptr = 234; // foo.b = 234;
}
Member functions are almost the same.
成员函数几乎是一样的。
struct Foo {
int a ();
int b ();
};
int main ()
{
Foo foo;
int (Foo :: * ptr) ();
ptr = & Foo :: a;
(foo .*ptr) (); // foo.a ();
ptr = & Foo :: b;
(foo .*ptr) (); // foo.b ();
}
#3
10
In a nutshell: You use ->
and .
if you know what member you want to access. And you use ->*
and .*
if you don't know what member you want to access.
简而言之:您使用->和。如果您知道要访问哪个成员。如果您不知道要访问的成员,则使用->*和.*。
Example with a simple intrusive list
一个简单的插入列表的例子
template<typename ItemType>
struct List {
List(ItemType *head, ItemType * ItemType::*nextMemPointer)
:m_head(head), m_nextMemPointer(nextMemPointer) { }
void addHead(ItemType *item) {
(item ->* m_nextMemPointer) = m_head;
m_head = item;
}
private:
ItemType *m_head;
// this stores the member pointer denoting the
// "next" pointer of an item
ItemType * ItemType::*m_nextMemPointer;
};
#4
6
So called "pointers" to members in C++ are more like offsets, internally. You need both such a member "pointer", and an object, to reference the member in the object. But member "pointers" are used with pointer syntax, hence the name.
在c++中,所谓的“指针”更像是内部的偏移量。您需要这样的成员“指针”和对象来引用对象中的成员。但是成员“指针”与指针语法一起使用,因此命名。
There are two ways you can have an object at hand: you have a reference to the object, or you have a pointer to the object.
有两种方法可以将对象放在手边:对对象有引用,或者有指向对象的指针。
For the reference, use .*
to combine it with a member pointer, and for the pointer, use ->*
to combine it with a member pointer.
对于引用,使用.*将其与成员指针合并,对于指针,使用->*将其与成员指针合并。
However, as a rule, don't use member pointers if you can avoid it.
但是,作为一个规则,如果可以避免,不要使用成员指针。
They obey pretty counter-intuitive rules, and they make it possible to circumvent protected
access without any explicit casting, that is, inadvertently…
它们遵循相当反直觉的规则,而且它们使绕过受保护访问而不进行任何显式强制转换成为可能,也就是说,无意中……
Cheers & hth.,
欢呼声& hth。
#5
5
When you have a normal pointer (to an object or a basic type), you would use *
to dereference it:
当您有一个普通指针(指向对象或基本类型)时,您将使用*来取消它:
int a;
int* b = a;
*b = 5; // we use *b to dereference b, to access the thing it points to
Conceptually, we're doing the same thing with a member function pointer:
概念上,我们对一个成员函数指针做同样的事情:
class SomeClass
{
public: void func() {}
};
// typedefs make function pointers much easier.
// this is a pointer to a member function of SomeClass, which takes no parameters and returns void
typedef void (SomeClass::*memfunc)();
memfunc myPointer = &SomeClass::func;
SomeClass foo;
// to call func(), we could do:
foo.func();
// to call func() using our pointer, we need to dereference the pointer:
foo.*myPointer();
// this is conceptually just: foo . *myPointer ();
// likewise with a pointer to the object itself:
SomeClass* p = new SomeClass;
// normal call func()
p->func();
// calling func() by dereferencing our pointer:
p->*myPointer();
// this is conceptually just: p -> *myPointer ();
I hope that helps explain the concept. We're effectively dereferencing our pointer to the member function. It's a little more complicated than that -- it's not an absolute pointer to a function in memory, but just an offset, which is applied to foo
or p
above. But conceptually, we're dereferencing it, much like we would dereference a normal object pointer.
我希望这有助于解释这个概念。我们实际上取消了指向成员函数的指针。它比这复杂一点——它不是内存中函数的绝对指针,而是一个偏移量,它被应用到foo或p上面。但从概念上讲,我们是去引用它,就像我们要去引用一个普通的对象指针一样。
#6
4
You cannot dereference pointer to members as normal pointers — because member functions require this
pointer, and you have to pass it somehow. So, you need to use these two operators, with object on one side, and pointer on another, e.g. (object.*ptr)()
.
不能将成员指针作为普通指针来取消引用——因为成员函数需要这个指针,并且必须以某种方式传递它。因此,您需要使用这两个操作符,一边是对象,另一边是指针,例如(object.*ptr)()。
Consider using function
and bind
(std::
or boost::
, depending on whether you write C++03 or 0x) instead of those, though.
考虑使用函数和bind (std::或boost::,取决于您是编写c++ 03还是0x),而不是这些。