(這是閱讀此答案后的問題)
我試過這段代碼:
#include <iostream>
class A {
public:
int a;
A(int val) : a{val}{}
int f(int);
int (A::*p)(int);
};
int A::f(int in) {
return in a;
}
int main() {
A a1(1000);
A a2(2000);
// Without these two lines, segmentation fault.
a1.p = &A::f; // no instance information.
a2.p = &A::f; // no instance information.
std::cout << a1.p << " " << a2.p << '\n';
std::cout << std::boolalpha << (a1.p == a2.p) << '\n';
std::cout << (a1.*(a1.p))(5) << '\n';
std::cout << (a1.*(a2.p))(5) << '\n';
std::cout << (a2.*(a1.p))(5) << '\n';
std::cout << (a2.*(a2.p))(5) << std::endl;
}
結果:
1 1
true
1005
1005 // the same result as above.
2005
2005 // the same result as above.
似乎
a1.p和a2.p是一樣的。成員函式的地址是否在通過附加實體名稱被取消參考和呼叫之前未分配?&A::f如果是這樣,如果沒有關于實體的資訊,分配的意義何在?
uj5u.com熱心網友回復:
非靜態成員函式有一個“隱藏”的第一個引數,它成為this函式內部的指標。因此實體不是函式本身的一部分,而是作為引數傳遞。
注意“隱藏”周圍的引號,因為它只隱藏在函式簽名中。當使用其他方式呼叫 e 成員函式時,它并沒有真正隱藏,而是像任何其他引數一樣實際傳遞。例如,如果使用std::bindor std::thread,則以實體作為實際引數呼叫非靜態成員函式。
例子:
struct thread_class
{
int value_;
explicit thread_class(int value)
: value_{ value }
{
}
void thread_func(int arg)
{
std::cout << "arg is " << arg << '\n';
std::cout << "value is " << value_ << '\n';
}
};
int main()
{
thread_class foo;
std::thread thread(&thread_class::thread_func, &foo, 123);
thread.join();
}
建構式的三個引數std::thread是要運行的函式,以及函式本身的引數。第一個是呼叫函式的物件,變成thisinside thread_func。
uj5u.com熱心網友回復:
看來 a1.p 和 a2.p 是一樣的。成員函式的地址是否在通過附加實體名稱被取消參考和呼叫之前未分配?
成員函式的地址與呼叫它的實體無關。從class.mem:
非靜態成員函式的型別是普通函式型別,非靜態資料成員的型別是普通物件型別。沒有特殊的成員函式型別或資料成員型別。
(強調我的)
出于多載決議的目的,如果成員函式是非常量且成員函式是 const ,則就好像非靜態成員函式具有型別的隱式物件引數。這個隱式物件引數基本上是指呼叫它的物件。X&const X&
現在來回答你的第二個問題:
如果是這樣,如果它沒有關于實體的資訊,那么分配 &A::f 的意義何在?
f用指標來標識成員成員p。例如,一個類中可以有多個成員函式。喜歡struct A{void f(); void g(int);int (A::*p)(int);};。因此,通過撰寫a1.p = &A::f,您是在告訴編譯器您希望將 的地址f分配給a1.p. 另請注意,非靜態資料成員的型別也是普通物件型別。
在取消參考指標時將提供有關實體的資訊(例如呼叫哪個實體),p就像您在(a1.*(a1.p))(5)和中所做的那樣(a2.*(a1.p))(5)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/519688.html
標籤:C 指针函数指针
上一篇:可以將特定型別的指標分配給指向與它的成員之一包含相同型別的聯合的指標嗎?
下一篇:如何用C中的函式更改字串值?
