是的,我见过this question和
this FAQ(错误的链接)
this FAQ,但我仍然不明白->*
和.*
意味着C++。
那些页面提供的信息约运营商(如超载),但似乎并没有很好地解释他们是。什么是指针 - 成员 - > *和。*运算符在C++中?
什么是->*
和.*
在C++中,和->
和.
相比,您何时需要使用它们?
是的,我见过this question和
this FAQ(错误的链接)
this FAQ,但我仍然不明白->*
和.*
意味着C++。
那些页面提供的信息约运营商(如超载),但似乎并没有很好地解释他们是。什么是指针 - 成员 - > *和。*运算符在C++中?
什么是->*
和.*
在C++中,和->
和.
相比,您何时需要使用它们?
我希望这个例子清楚你的东西
//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();
现在,你不能用x.somePointer()
,或px->somePointer()
因为在十类没有这样的成员对于特殊的成员函数指针调用语法使用...只是自己尝试几个例子,你会习惯它
添加**所需的**额外大括号来补偿运算符优先级。 –
@阿门:哦,我现在看到发生了什么......我从来没有见过或需要这样的事情。这很酷(+1),但我现在的问题是:“指针”与普通函数指针有什么不同,它需要不同的语法? (例如它是否更大?) – Mehrdad
@Mehrdad:关键是要调用普通函数,只需提供参数。但是在非静态成员函数的情况下,你还需要一个你想调用函数的对象。因此,新的语法。 –
简而言之:如果你知道你想访问的成员,你使用->
和.
。如果您使用->*
和.*
,并且不知道知道您想访问哪个成员。
实施例用简单的侵入列表
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;
};
第一句话+1,但我的生活中从来没有*我*不知道我想访问哪个成员,哈哈。 :) – Mehrdad
所谓的“指针”在C++成员更像偏移,在内部。您需要这样一个成员“指针”和一个对象来引用对象中的成员。但成员“指针”用于指针语法,因此名称。
有两种方法可以使对象在手边:您有对象的引用,或者您有指向对象的指针。
为了便于参考,请使用.*
将其与成员指针结合使用,对于指针,请使用->*
将其与成员指针组合使用。
但是,通常情况下,如果可以避免使用成员指针,则不要使用成员指针。
他们服从非常违反直觉的规则,并且它们可以规避protected
访问,而不需要任何明确的转换,也就是不经意间&hellip;
干杯&心连心,
+1为解释它没有代码。 :)问题:为什么我们不能像普通函数那样获取函数的地址?是指向一个成员函数的指针与指向其他某个函数的指针不同? (例如它是否更大?) – Mehrdad
@Mehrdad:如果您可以有一个指向仅限于非虚拟成员函数的成员函数的指针,那么它确实可能只是地址。但是,虚拟或不是不是成员函数指针类型的一部分。因此,它的表示需要包含一些关于当前值是否指向虚拟函数的信息,如果是虚拟的,则针对基于vtable的实现信息来确定指针类型与类的vtable中的偏移量有关的信息。 –
不能解引用指针成员正常的指针 - 因为成员函数需要this
指针,你必须以某种方式通过。所以,你需要使用这两个操作符,一边是对象,另一边是指针,例如(object.*ptr)()
。尽管如此,考虑使用function
和bind
(std::
或boost::
,取决于您是否编写C++ 03或0x)而不是这些。
我认为这可能是这里最好的解释。 – Marcin
编辑:顺便说一句,它变得很奇怪的virtual member functions pointers。
成员变量:
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;
}
成员函数几乎是一样的。
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();
}
+1表示该语法适用于所有成员,而不仅仅是成员函数。尽管我发现指向成员变量的指针很少被使用,尽管它们有许多相当有趣的潜在应用。 –
当你有一个正常的指针(对象或基本类型),你可以使用*
取消对它的引用:
int a;
int* b = a;
*b = 5; // we use *b to dereference b, to access the thing it points to
从概念上讲,我们正在做同样的事情成员函数指针:
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 ();
我希望能帮助解释这个概念。我们正在有效地解除引用我们的成员函数的指针。它比这更复杂一点 - 它不是指向内存函数的绝对指针,而是一个偏移量,它应用于上面的foo
或p
。但从概念上讲,我们正在取消引用它,就像我们将引用一个普通的对象指针一样。
我认为[这个FAQ](http://www.parashift.com/c++-faq-lite/pointers-to-members.html)对它进行了相当好的解释。 –
@Rob:我不相信我发布了错误的链接。 X___X这是我打算发布的,而不是MSDN! - 我看过它,但是我对它不了解太多。他们所说的只是“类型不同”,但我发现那种混淆...... – Mehrdad