Pointer ke fungsi bukan pointer data biasa karena tidak dapat disimpan dalam pointer * kosong. Meskipun demikian, tampaknya saya dapat menyimpan salinan fungsi-pointer dalam memori dinamis (dalam gcc dan dentang) seperti pada kode di bawah ini. Apakah kode tersebut legal menurut Standar C ++, atau mungkin ini semacam ekstensi kompiler?
Selain itu, pointer yang dihasilkan ke function-pointer berperilaku sebagai pointer data biasa: Saya dapat menyimpannya di void * dan mengambilnya dari void * oleh static_cast. Apakah perilaku ini dijamin oleh Standar?
int main()
{
extern void fcn();
void (*fcnPtr)() = &fcn;
void (**ptrToFcnPtr)() = nullptr;
//Make the copy of fcnPtr on the heap:
ptrToFcnPtr = new decltype(fcnPtr)(fcnPtr);
//Call the pointed-to function :
(**ptrToFcnPtr)();
//Save the pointer in void* :
void *ptr = ptrToFcnPtr;
//retrieve the original ptr:
auto myPtr = static_cast< void(**)() > (ptr) ;
//free memory:
delete ptrToFcnPtr ;
}
std::function
sebagai gantinya.new
dilemparkanvoid*
.void* ptr = &fcnPtr;
berfungsi dengan baik, karenafcnPtr
merupakan objek, bukan fungsi.std::function
adalah wadah tipe-terhapus untuk menyimpan callable sewenang-wenang, bukan pengganti pengganti fungsi pointer ...std::function
. Ini bagus untuk kemampuannya menyimpan fungsi "polimorfik" (yaitu apa saja dengan tanda tangan yang benar, bahkan jika itu berisi keadaan seperti dalam kasus beberapa lambda), tetapi itu juga menambahkan overhead yang mungkin tidak diperlukan. Pointer ke fungsi adalah POD. Astd::function
bukan.void*
, jadi dalam konteks pertanyaan inistd::function
tampaknya persis apa yang mereka cari. Saya setuju bahwa pemecatan umum pointer fungsi SPD tidak sehat.Jawaban:
Sementara pointer fungsi bukan pointer objek, "pointer ke fungsi beberapa tipe" masih merupakan tipe objek [basic.types] / 8 . Dengan demikian, fungsi pointer adalah objek itu sendiri, hanya hal yang mereka tuju bukan.
Dengan demikian, Anda yakin dapat membuat objek tipe pointer fungsi melalui ekspresi baru ...
sumber
Sebenarnya, menyimpan pointer fungsi sebagai
void*
kondisional didukung. Ini berarti bahwa dapat atau tidak dapat disimpan tergantung pada implementasi bahasa. Jika implementasi bahasa mendukung pemuatan dinamis, maka konversi penunjuk fungsi divoid*
mungkin didukung. GCC, Dentang dan MSVC semua mendukung ini:Tentu. Semua pointer, termasuk pointer fungsi, adalah objek dan semua objek dapat dialokasikan secara dinamis.
Pointer fungsi adalah sebuah objek. Pointer ke pointer fungsi tidak hanya "berperilaku", tetapi adalah pointer ke objek.
Konversi antara pointer ke void dan pointer ke objek diperbolehkan, ya. Dan konversi pulang pergi dijamin untuk menghasilkan pointer asli.
sumber