是的,我見過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