Access a private virtual member-function through pointers - c++

class foo{
public:
int n;
private:
virtual void sayHi(){
cout<<"Hi there!";
}
};
How do I get the address of sayHi()??
main(){
foo f;
typedef void(*fptr)();
fptr func = reinterpret_cast<fptr>((&f)[0]);
(*func)();
}
The code above didn't work.
I know that the first 8 bytes of "f" object is a pointer to a virtual table where it contains the pointers to the functions, I'm using 64-bits machine. I'm basically trying to call the sayHi() through its pointer rather than calling it directly from f, since sayHi() is private anyway! How would I do this? Am I apportioning it right??

You cannot simply have a pointer to a non-static member function and call it without an object. The most straight-forward way to interpret your question would be using a pointer-to-member as in:
auto fptr = &foo::sayHi;
foo f;
(f.*fptr)();
Now, you say you want to call it without having to go through f. It's not clear exactly what this means. Using a lambda is probably good enough to create a callable that works as you want
auto func = [] { return foo{}.sayHi(); };
func(); // call
or using a specific object and capturing it by reference (shown) or by value
foo f;
auto func = [&f] { return f.sayHi(); };
func();

sayHi() is a non-static method of a class. You need to use a pointer-to-method instead of a raw pointer (the implementation of a method pointer is compiler-specific, so assuming the internal layout of the pointer-to-method is not portable).
Also, sayHi() is private to foo, so main() cannot access it directly. You need to either:
declare sayHi() as public:
class foo
{
int n;
public:
virtual void sayHi(){
cout << "Hi there!";
}
};
int main()
{
typedef void (foo::*fptr)();
fptr func = &foo::sayHi;
foo f;
(f.*func)();
return 0;
}
make main() be a friend of foo:
class foo
{
int n;
virtual void sayHi(){
cout << "Hi there!";
}
friend int main();
};
int main()
{
typedef void (foo::*fptr)();
fptr func = &foo::sayHi;
foo f;
(f.*func)();
return 0;
}

Well, ISO C++ forbids taking the address of a bound member function to form a pointer to member function. However, you can do something like this, if it helps. You may check the result here.
#include <iostream>
using namespace std;
class foo{
int n;
public:
virtual void sayHi(){
cout<<"Hi there!";
}
};
typedef void(*fptr)();
int main() {
auto func = reinterpret_cast<fptr>(&foo::sayHi);
(*func)();
return 0;
}

Related

Function of Class in an Array [duplicate]

I have a class A which contains member functions foo() and bar() which both return a pointer to class B. How can I declare an array containing the functions foo and bar as a member variable in class A? And how do I call the functions through the array?
The member function pointer syntax is ReturnType (Class::*)(ParameterTypes...), so e.g.:
typedef B* (A::*MemFuncPtr)(); // readability
MemFuncPtr mfs[] = { &A::foo, &A::bar }; // declaring and initializing the array
B* bptr1 = (pointerToA->*mfs[0])(); // call A::foo() through pointer to A
B* bptr2 = (instanceOfA.*mfs[0])(); // call A::foo() through instance of A
See e.g. this InformIT article for more details on pointers to members.
You might also want to look into Boost.Bind and Boost.Function (or their TR1 equivalents) which allow you to opaquely bind the member-function-pointers to an instance:
typedef boost::function<B* ()> BoundMemFunc;
A instanceOfA;
BoundMemFunc mfs[] = {
boost::bind(&A::foo, &instanceOfA),
boost::bind(&A::bar, &instanceOfA)
};
B* bptr = mfs[0](); // call A::foo() on instanceOfA
To use such an array as a member, note that you can't initialize arrays using the member initializer list. Thus you can either assign to it in the constructor body:
A::A {
mfs[0] = &A::foo;
}
... or you use a type that can actually be initialized there like std::vector or boost::array:
struct A {
const std::vector<MemFuncPtr> mfs;
// ...
};
namespace {
std::vector<MemFuncPtr> init_mfs() {
std::vector<MemFuncPtr> mfs;
mfs.push_back(&A::foo);
mfs.push_back(&A::bar);
return mfs;
}
}
A::A() : mfs(init_mfs()) {}
What you're looking for are pointers to member functions. Here is a short sample that shows their declaration and use:
#include <iostream>
class B {
public:
B(int foo): foo_(foo) {
std::cout << "Making a B with foo_ = " << foo_ << std::endl;
}
~B(void) {
std::cout << "Deleting a B with foo_ = " << foo_ << std::endl;
}
int foo_;
};
class A {
public:
A(void) {
funcs_[0] = &A::foo;
funcs_[1] = &A::bar;
}
B* foo(void) {
return new B(3);
}
B* bar(void) {
return new B(5);
}
// Typedef for the member function pointer, for everyone's sanity.
typedef B* (A::*BMemFun)(void);
BMemFun funcs_[2];
};
int main(int argc, char *argv[]) {
A a;
for (int i = 0; i < 2; ++i) {
A::BMemFun func = a.funcs_[i];
// Call through the member function pointer (the .* operator).
B* b = (a.*func)();
delete b;
}
return 0;
}
The C++ FAQ section on pointers to member functions is where I found all this information.
C++ that's not ancient (read: C++11 and later) makes this all easier. In modern C++, you can do
#include <vector>
class B;
class A {
public:
B* foo() {
// return something;
return nullptr;
}
B* bar() {
// return something;
return nullptr;
}
//C++ 11: functional brings std::function, which has zero overhead
//but is actually a useful type with which one can work
std::vector<std::function<B*()>> container;
/* [=]() { return foo(); }
* that's a lambda. In practice it "compiles away", i.e. calling
* the lambda function is the same as calling foo or bar directly
* Note how [=] means we're passing in "this", so that we can
* actually call foo().
*/
A() : container{{[=]() { return foo(); }}, {[=]() { return bar(); }}} {}
};
(Try on godbolt compiler explorer)
Here's a more complete example showcasing what to do with these.
An architectural remark: Be careful with pointers to non-static member functions. What happens if your instance of A gets destroyed, but you still have a function handle to a member function? Right, hell freezes over: There's no object anymore to which this method belongs, so results are catastrophic.

Call a C-style function address with std::bind and std::function.target using a method from object

I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:
#include <functional>
#include <iostream>
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
std::function<void(int)> f;
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
TestClass t;
t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
foo( t.f.target<void(int)>() );
return 0;
}
What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:
error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
return const_cast<_Functor*>(__func);
As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.
This is a dirty little hack but should work
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
global_variable_hack->foo(x);
}
int main() {
TestClass t;
global_variable_hack = &t;
foo(hacky_function);
return 0;
}
//can also be done with a lambda without the global stuff
int main() {
static TestClass t;
auto func = [](int x) {
t->foo(x); //does not need to be captured as it is static
};
foo(func); //non-capturing lambas are implicitly convertible to free functions
}

Can a default lambda parameter have access privilege like the class itself? [duplicate]

Let's say, I have a class:
class A {
int a;
};
And I have a lambda:
auto function = [](A* a) {
a->a; // <== gives an error in this line.
};
function(new A);
Is there any way to use a private member/method inside a lambda? - It's not necessary to pass the pointer to the lambda - it may be a capture-by or something else.
All reasonable schemes are welcome.
You can do it by creating a friend function that returns the lambda function. It inherits the friend access:
struct A {
friend std::function<void(A&, int)> f();
private:
int i;
void test() {std::cout << "test: " << i << "\n";}
};
std::function<void(A&, int)> f() {
return [] (A &a, int i) {a.i = i; a.test(); };
}
int main() {
A a;
f()(a, 13);
return 0;
}
In order to make a lambda a friend, you need to befriend a class or a function where the lambda is defined. Here is a complete example:
#include <iostream>
using namespace std;
class A {
int a;
public:
A(int _a) : a(_a) {}
friend int foo(A*); // Declare foo(A*) a friend of A
};
int foo(A* aa) {
auto function = [](A* a) {
return a->a; // Now foo(A*) can access A::a, which is private
};
return function(aa);
}
int main() {
A a(123);
cout << foo(&a) << endl;
return 0;
}
Here is a running demo on ideone.
using std::function takes extra resource, so I recomendet using friend/or method function to access private member (friend function implicit inlined):
class A{
int a;
friend int access_member(A*a){ return a->a;}
};
-----------------------------------------
auto function = [](A*a){ return access_member(a); }
Live example
EDIT: I personally like std::function, but don't forgot, std::function always takes extra memory resources, and may not inlined , so if you may implement your source without std::function, don't use std::function. See, How is std::function implemented?
Also, Lambda to std::function conversion performance

How to make the lambda a friend of a class?

Let's say, I have a class:
class A {
int a;
};
And I have a lambda:
auto function = [](A* a) {
a->a; // <== gives an error in this line.
};
function(new A);
Is there any way to use a private member/method inside a lambda? - It's not necessary to pass the pointer to the lambda - it may be a capture-by or something else.
All reasonable schemes are welcome.
You can do it by creating a friend function that returns the lambda function. It inherits the friend access:
struct A {
friend std::function<void(A&, int)> f();
private:
int i;
void test() {std::cout << "test: " << i << "\n";}
};
std::function<void(A&, int)> f() {
return [] (A &a, int i) {a.i = i; a.test(); };
}
int main() {
A a;
f()(a, 13);
return 0;
}
In order to make a lambda a friend, you need to befriend a class or a function where the lambda is defined. Here is a complete example:
#include <iostream>
using namespace std;
class A {
int a;
public:
A(int _a) : a(_a) {}
friend int foo(A*); // Declare foo(A*) a friend of A
};
int foo(A* aa) {
auto function = [](A* a) {
return a->a; // Now foo(A*) can access A::a, which is private
};
return function(aa);
}
int main() {
A a(123);
cout << foo(&a) << endl;
return 0;
}
Here is a running demo on ideone.
using std::function takes extra resource, so I recomendet using friend/or method function to access private member (friend function implicit inlined):
class A{
int a;
friend int access_member(A*a){ return a->a;}
};
-----------------------------------------
auto function = [](A*a){ return access_member(a); }
Live example
EDIT: I personally like std::function, but don't forgot, std::function always takes extra memory resources, and may not inlined , so if you may implement your source without std::function, don't use std::function. See, How is std::function implemented?
Also, Lambda to std::function conversion performance

c++ calling method from outside of a class

Ok, I reduced my problem to something that looks really silly but I simply cannot understand why this:
#include <iostream>
class ABC{
public:
void Print() { std::cout<<"ABC_TEST!\n"; }
};
int main(){
Print();
return 0;
}
Gives me: error: identifier "Print" is undefined
Thanks in advance!
It should be like this :
#include <iostream>
class ABC{
public:
void Print() { std::cout<<"ABC_TEST!\n"; }
};
int main(){
ABC abc;
abc.Print();
return 0;
}
You need to create an object of type ABC before you can call instance methods(or member functions which are not static)
Alternatively, Print() can be a static function and you will be able to call it with the :: operator.
class ABC {
public:
static void Print() { std::cout << "ABC_TEST\n"; }
};
int main()
{
ABC::Print();
return 0;
}
Above all else, Print() can also be a global function:
void Print()
{
std::cout << "ABC_TEST\n" ;
}
int main()
{
Print();
return 0;
}
Print() is a member function of ABC, so you can only call it on an instance of ABC:
ABC abc;
abc.Print();
As a completely unrelated note, in C++ a return with value 0 is implied, so it is not necessary to write return 0.
Print() is a member function of your ABC class, you need an object to invoke it on:
int main()
{
ABC abc; // This creates an instance of ABC
abc.Print();
// ^^^^
// This invokes member function `Print()` on the object abc.
return 0;
}
The address of abc will be passed as an implicit first parameter to function Print(): that parameter will be accessible inside of Print() (more generally, inside an invoked member function) as the this pointer.
If you try calling Print() as if it were a non-member, free function, no implicit this pointer would be passed, and it makes sense that the compiler complains about it.
If you want to be able to invoke Print() the way you did, you should make it a non-member function:
void Print() { std::cout<<"ABC_TEST!\n"; }
int main()
{
Print(); // This is fine now!
}