Is there a way to get function pointer for a member function that is private inside a class
class A
{
public:
void callMe()
{
cout<<__FUNCTION__<<endl;
}
private:
void fooMem()
{
cout<<__FUNCTION__<<endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
auto fp = &A::fooMem;
return 0;
}
Compiling this in vs 2012 c++ compiler causes below error
error C2248: 'A::fooMem' : cannot access private member declared in class 'A'
see declaration of 'A::fooMem'
I looked into a amazing solution to a similar problem (though I am not very clear how this actually works, if someone can explain that would be great too), Here I want the address of the member not to invoke it.
The reason I am asking for the address is I'll be patching this function with a different implementation.
The class as such is not modifiable, But I can inherit if that can help achieve this.
Since you cannot modify the original class, it would be much easier to simply inherit the class and create a duplicate of the function in a public memberspace.
I tried this out and it works as expected, at least with g++:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
class A
{
public:
void aFunction()
{
cout<<"This is aFunction"<<endl;
}
private:
void anotherFunction()
{
cout<<"This is anotherFunction"<<endl;
}
};
class B: public A
{
public:
void anotherFunction()
{
cout<<"This is also anotherFunction, but it's accessible!"<<endl;
}
};
int main(int argc, char* argv[])
{
A firstClass;
B coach;
firstClass.aFunction();
coach.anotherFunction();
return 0;
}
When I run this code I get the following output:
$ ./a.out
This is aFunction
This is also anotherFunction, but it's accessible!
Proving the compiler understood which version of anotherFunction to use.
Related
I want to determine if a function definition actually exist in a class and call that function only if it exists (not just declared). Idea is function declaration will always be present in the class header file but it's implementation (function definition) may or may not be included in the compilation based on the some flags. Catch is that I can not use compiler flags in the source cpp files. Below is what I want to achieve:
class Base {
public:
void feature1(int x); // Definition always present
void feature2(int y); // Definition always present
void feature3(int z); // Definition may (or may not) be present in another cpp file / library
};
int main(int argc, char *argv[]) {
Base a1;
if (a1.feature3 is available) { // pseudo code
a1.feature3(5);
} else {
printf("feature3 is not available\n");
}
return 0;
}
Can someone please help with a possible solution.
If one method is not defined (but only declare) and you try reference it, linker won't be able to link. Maybe you could try a different approach to the problem (but depends on the requirements that you have), you could try using polymorphism like so:
class Base
{
public:
virtual void feature3(){throw NotImplementException()}
}
class DerivedWithFeature3 : public Base
{
public:
void feature3(){/*do something*/}
}
int main(int argc, char *argv[]) {
Base a1;
try
{
a1.feature3(5);
}catch(NotImplementException&)
{
printf("feature3 is not available\n");
}
return 0;
}
The weak symbol should be able to do this for you:
class Base {
...
...
void feature3(int z) __attribute__((weak));
}
int main(int argc, char *argv[]) {
Base a1;
if (a1.feature3) {
a1.feature3(5);
} else {
printf("feature3 is not available\n");
}
return 0;
}
I'm trying to set a reference of a non-static function in c++. The function I'm referencing is not from the same c++ file, and I get and error saying :
Cannot create a non-constant pointer to member function.
Main.cpp
#include <iostream>
#include "Test.hpp"
class testClass {
public:
void (*update) (void);
};
int main() {
testClass tc;
test t;
tc.update = &t.update; //This is where the error occurs
return 0;
}
Test.hpp
#ifndef Test_hpp
#define Test_hpp
#include <stdio.h>
class test {
public:
void update() {
//Do something
}
};
#endif /* Test_hpp */
My question is how do you do this without setting update in test class to static?
static void update() {
//Do something
}
Using this code it works, but like I've stated I do not want this functiont to be static.
EDIT :
Because I'm stupid I failed to mention that the class test should be able to be different. Also to the answers I got already I learned that tc.update = &t.update; is wrong.
For Example :
#include <iostream>
#include "Test.hpp"
#include "anotherTestClass.hpp"
//I do not want to use templates if possible
class testClass {
public:
void (*update)(void);
};
int main() {
testClass tc;
test t;
tc.update = &test.update; //I know this is wrong now.
testClass tc2;
anotherTestClass atc;
tc2.update = &atc.update;
//p.s. I'm bad with c++
}
And the error i get now is.
Assigned to 'void (*)()' from incompatible type 'void (test::*)()'
One more thing is I'm using XCode to program, which I believe uses LLVM-GCC 4.2 as the compiler.
class test {
public:
void update() {
//Do something
}
};
class testClass {
public:
void (test::* update) (void);
};
int main() {
testClass tc;
test t;
tc.update = &test::update;
return 0;
}
Your approach is essentially wrong.
Member Function Pointers.
The member in the testClass:
void (*update) (void);
is a function pointer, which is different to a method function pointer. That why in order to compile you should switch to a static method (which is essentially a "normal" function).
A method function pointer should containt the static information about the class the method belongs.
Practically the right way is:
void (test::* ptr_method)(void); // a member pointer to test class
In that way the variable named ptr_method is a method of the class test pointer.
Then,
Get the Address of a method.
Your statement:
tc.update = &t.update; //This is where the error occurs
is simply wrong. The address of a class method is something which is not related with the object of that class.
You can obtain the address of a method with the syntax:
&CLASS_NAME::METHOD_NAME;
Indeed, that statement should be something like:
tc.update = &test::update;
Additional suggestions.
Call a method by means of a method pointer.
Once you have a method pointer it is not so immediate to call the method associated with it.
As I said before, the address of the method is not related with the object of that class, so if you want to call the method you need to provide to the compiler the information about the object on which the method has to be called.
The syntax is something like:
(OBJECT.*METHOD_POINTER)(ARGS...);
Here, I propose a simple demo which shows all what I've just said.
I've begun coding in C++ some months ago and now I have been trying to code this one Tic Tac Toe game in an OO manner, however I have had some trouble calling a member function from, let's say just for the sake of the argument, class A through another member function from class B.
Here is a piece of code just to clear it all out:
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
class A
{
private:
char cBlocks[9];
public:
void setA(int nBlock, const char cCharacter)
{
cBlocks[nBlock] = cCharacter;
}
};
class B
{
private:
char cB;
public:
char getB()
{
return cB;
}
void makePlay(int nB)
{
const char cChar = getB();
A::setA(nB, cChar);
}
};
So, when I try to make this call, from within the B::makePlay(int) function:
A::setA(nB, cChar);
The following error is displayed: "Call to non-static member function without an object argument" .
How can I solve this ? What is wrong ?
All help is appreciated! Thank you!
You need to call setA on an instance of class A
A a;
a.setA(nB, cChar);
I’m trying to puzzle out how clang determines what C++ template static member variables require instantiation, and I’m seeing some behavior that has me confused.
Given the following code:
#include <stdio.h>
#include <typeinfo>
int report(const char *name)
{
printf("Reporting class: %s\n", name);
return 0;
}
template<typename ReportedClass>
class reported_class
{
public:
reported_class()
{
_reported_instances++;
}
private:
static int _reported_instances;
};
template<typename ReportedClass>
int reported_class<ReportedClass>::_reported_instances = report(typeid(ReportedClass).name());
class foo : reported_class<foo>
{
public:
int baz() { return 0; }
};
class bar : reported_class<bar>
{
public:
bar() { }
int baz() { return 0; }
};
int main(int argc, char **argv)
{
return 0;
}
When I run it, I see the following:
$ c++ -v
Apple LLVM version 5.0 (clang-500.0.68) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix
$ c++ test.cpp
$ ./a.out
Reporting class: 3bar
$
Why is the static for reported_class being instantiated, but not the one for foo? The only difference appears to be the presence of a constructor, but I’d expect the reported_class constructor to be called in either case (therefore forcing static instantiation due to use in the constructor). Is there a reason for this in the standard that I’m not aware of, and is this something that can be relied upon?
gcc-4.7.3 displays the same behavior, so I assume that this is something that I"m misunderstanding.
Apparently in the not shown main function you're not instantiating either class.
Then there's no reason for the compiler to generate a default constructor for class foo.
And without that, there's no code that instantiates reported_class<foo>.
#include <iostream>
using namespace std;
class CClass
{
private:
friend class CFriend;
static void privateFunc(){std::cout << "privateFunc" << std::endl;};
};
class CFriend
{
public:
void privateFunc(){privateFunc();};
};
int main(int argc, char* argv[])
{
CFriend b;
b.privateFunc();
return 0;
}
This code compiles, but using the gcc-compiler or http://www.ideone.com/ the program crashes. Is that a compiler error or do I need to understand more about friend classes?
You've created infinite recursion:
void privateFunc(){privateFunc();};
Use instead:
void privateFunc(){CClass::privateFunc();};
There's nothing wrong with friend declaration.
Infinite recursion in your object, creating a Stack Overflow !!!
You must explicitely call your friend class :
void privateFunc(){CClass::privateFunc();};
You have the function called privateFunc() in CFriend class as well. This means when inside that function you call privateFunc() it will call itself (how should it know you mean the other class) thus entering a recursive infinite loop.
You mean
void privateFunc()
{
CClass::privateFunc();
}
using CClass:: to specify completely the name of the function you mean.
It is crashing because of stack overflow you would beed scope resolution to call static function
class CFriend
{
public:
void privateFunc(){CClass::privateFunc();};
};
You have a stack overflow from an infinitely recursive function. CFriend::privateFunc is calling itself. Change it to void privateFunc() {CClass::privateFunc();}
Scope distinctions, public, private, protected and friend, have not runtime consequences at all. They are strictly for the compilier to decide what is legal or not. You could #define private public and the resulting executable wouldn't change.