Last active
February 29, 2024 06:24
-
-
Save mshafae/396db34b08fb9d3b553358778d176f56 to your computer and use it in GitHub Desktop.
CPSC 120 C++ pointers to functions and member functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Gist https://gist.github.com/mshafae/396db34b08fb9d3b553358778d176f56 | |
// Filename cpsc120_function_pointer.cc | |
// CompileCommand clang++ -std=c++17 cpsc120_function_pointer.cc | |
// Demonstrates how to work with functions and member functions as pointers. | |
// Generally speaking, don't do this unless you need to. You will probably | |
// find that function objects and lambda expressions will get you more mileage | |
// in C++ however this knowledge is useful. | |
#include <iostream> | |
#include <string> | |
#include <cstdlib> | |
class Foo { | |
private: | |
int value_; | |
public: | |
Foo() : value_{3} {}; | |
void Sum(int other_value) { value_ += other_value; } | |
int Value() { return value_; } | |
}; | |
int Square(int num) { | |
return num * num; | |
} | |
int AscendingCompare(const void* lhs, const void* rhs) { | |
int lhs_int = *static_cast<const int*>(lhs); | |
int rhs_int = *static_cast<const int*>(rhs); | |
return lhs_int - rhs_int; | |
} | |
int main(int argc, char const *argv[]) { | |
int (*func_ptr)(int) = Square; | |
// You can also say | |
// The difference is like the difference between | |
// int arr[4]; | |
// int* p = arr; | |
// int* q = &arr; | |
int (*func_ptr_variation)(int) = □ | |
std::cout << func_ptr(4) << "\n"; | |
std::cout << func_ptr_variation(5) << "\n"; | |
Foo f; | |
// error: call to non-static member function without an object argument | |
// void (Foo::*member_function_ptr)(int) = Foo::Sum; | |
void (Foo::*member_function_ptr)(int) = &Foo::Sum; | |
// To call the member function (that is not static), we need to start | |
// with an instance and then follow the pointer from there. | |
(f.*member_function_ptr)(17); | |
// We expect to see 20 | |
std::cout << f.Value() << "\n"; | |
// What if we have a pointer to an instance | |
Foo* foo_ptr = &f; | |
(foo_ptr->*member_function_ptr)(4); | |
// We expect to see 24 | |
std::cout << f.Value() << "\n"; | |
int numbers[10]{10, 6, 8, 7, 4, 5, 3, 2, 9, 1}; | |
for(const auto num : numbers) { | |
std::cout << num << ", "; | |
} | |
std::cout << "\n"; | |
// The prototype for qsort is typically | |
// void qsort(void *base, size_t nel, size_t width, | |
// int (*compar)(const void *, const void *)); | |
qsort(numbers, 10, sizeof(int), AscendingCompare); | |
for(const auto num : numbers) { | |
std::cout << num << ", "; | |
} | |
std::cout << "\n"; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment