Calling C++ class methods via a function pointer
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
How do I obtain a function pointer for a class member function, and later call that member function with a specific object? I’d like to write:
class Dog : Animal
{
Dog ();
void bark ();
}
…
Dog* pDog = new Dog ();
BarkFunction pBark = &Dog::bark;
(*pBark) (pDog);
…
Also, if possible, I’d like to invoke the constructor via a pointer as well:
NewAnimalFunction pNew = &Dog::Dog;
Animal* pAnimal = (*pNew)();
Is this possible, and if so, what is the preferred way to do this?
c++ function-pointers class-method
|
show 1 more comment
How do I obtain a function pointer for a class member function, and later call that member function with a specific object? I’d like to write:
class Dog : Animal
{
Dog ();
void bark ();
}
…
Dog* pDog = new Dog ();
BarkFunction pBark = &Dog::bark;
(*pBark) (pDog);
…
Also, if possible, I’d like to invoke the constructor via a pointer as well:
NewAnimalFunction pNew = &Dog::Dog;
Animal* pAnimal = (*pNew)();
Is this possible, and if so, what is the preferred way to do this?
c++ function-pointers class-method
I still don't really understand 'why' if you want to call a objects member function then simply pass a pointer to the object? If people complain that because it enables you to encapsulate the class better why not make an interface class that all class inherit from?
– Chad
Sep 28 '09 at 8:39
It can be useful in implementing something like the command pattern although many people would use boost::function to hide the raw member pointer mechanics.
– CB Bailey
Sep 28 '09 at 8:45
Thanks for the comment. Just after so many years of programing I've seen it used all over the place. I just consider passing a object cleaner and simpler.
– Chad
Sep 28 '09 at 8:56
7
Why do you allocate that dog dynamically? You then have to manually delete the object, too. This looks a lot like you're coming from Java, C# or some other comparable language and still fight with C++. A plain automatic object (Dog dog;
) is more likely what you want.
– sbi
Sep 28 '09 at 9:18
1
@Chad: I would mostly agree but there are times where passing a reference would be more costly. Consider a loop that is iterating over some type of data (parsing, calculation, etc..) than being able to call a function based on some if/else calculations imposes a cost where just calling the pointed too function could avoid such if/then/else checks if these checks could be done before entering the loop.
– Eric
Oct 25 '12 at 18:04
|
show 1 more comment
How do I obtain a function pointer for a class member function, and later call that member function with a specific object? I’d like to write:
class Dog : Animal
{
Dog ();
void bark ();
}
…
Dog* pDog = new Dog ();
BarkFunction pBark = &Dog::bark;
(*pBark) (pDog);
…
Also, if possible, I’d like to invoke the constructor via a pointer as well:
NewAnimalFunction pNew = &Dog::Dog;
Animal* pAnimal = (*pNew)();
Is this possible, and if so, what is the preferred way to do this?
c++ function-pointers class-method
How do I obtain a function pointer for a class member function, and later call that member function with a specific object? I’d like to write:
class Dog : Animal
{
Dog ();
void bark ();
}
…
Dog* pDog = new Dog ();
BarkFunction pBark = &Dog::bark;
(*pBark) (pDog);
…
Also, if possible, I’d like to invoke the constructor via a pointer as well:
NewAnimalFunction pNew = &Dog::Dog;
Animal* pAnimal = (*pNew)();
Is this possible, and if so, what is the preferred way to do this?
c++ function-pointers class-method
c++ function-pointers class-method
edited Apr 16 '10 at 20:24
Jon Seigel
10.1k84786
10.1k84786
asked Sep 28 '09 at 8:30
Tony the PonyTony the Pony
21.5k55160262
21.5k55160262
I still don't really understand 'why' if you want to call a objects member function then simply pass a pointer to the object? If people complain that because it enables you to encapsulate the class better why not make an interface class that all class inherit from?
– Chad
Sep 28 '09 at 8:39
It can be useful in implementing something like the command pattern although many people would use boost::function to hide the raw member pointer mechanics.
– CB Bailey
Sep 28 '09 at 8:45
Thanks for the comment. Just after so many years of programing I've seen it used all over the place. I just consider passing a object cleaner and simpler.
– Chad
Sep 28 '09 at 8:56
7
Why do you allocate that dog dynamically? You then have to manually delete the object, too. This looks a lot like you're coming from Java, C# or some other comparable language and still fight with C++. A plain automatic object (Dog dog;
) is more likely what you want.
– sbi
Sep 28 '09 at 9:18
1
@Chad: I would mostly agree but there are times where passing a reference would be more costly. Consider a loop that is iterating over some type of data (parsing, calculation, etc..) than being able to call a function based on some if/else calculations imposes a cost where just calling the pointed too function could avoid such if/then/else checks if these checks could be done before entering the loop.
– Eric
Oct 25 '12 at 18:04
|
show 1 more comment
I still don't really understand 'why' if you want to call a objects member function then simply pass a pointer to the object? If people complain that because it enables you to encapsulate the class better why not make an interface class that all class inherit from?
– Chad
Sep 28 '09 at 8:39
It can be useful in implementing something like the command pattern although many people would use boost::function to hide the raw member pointer mechanics.
– CB Bailey
Sep 28 '09 at 8:45
Thanks for the comment. Just after so many years of programing I've seen it used all over the place. I just consider passing a object cleaner and simpler.
– Chad
Sep 28 '09 at 8:56
7
Why do you allocate that dog dynamically? You then have to manually delete the object, too. This looks a lot like you're coming from Java, C# or some other comparable language and still fight with C++. A plain automatic object (Dog dog;
) is more likely what you want.
– sbi
Sep 28 '09 at 9:18
1
@Chad: I would mostly agree but there are times where passing a reference would be more costly. Consider a loop that is iterating over some type of data (parsing, calculation, etc..) than being able to call a function based on some if/else calculations imposes a cost where just calling the pointed too function could avoid such if/then/else checks if these checks could be done before entering the loop.
– Eric
Oct 25 '12 at 18:04
I still don't really understand 'why' if you want to call a objects member function then simply pass a pointer to the object? If people complain that because it enables you to encapsulate the class better why not make an interface class that all class inherit from?
– Chad
Sep 28 '09 at 8:39
I still don't really understand 'why' if you want to call a objects member function then simply pass a pointer to the object? If people complain that because it enables you to encapsulate the class better why not make an interface class that all class inherit from?
– Chad
Sep 28 '09 at 8:39
It can be useful in implementing something like the command pattern although many people would use boost::function to hide the raw member pointer mechanics.
– CB Bailey
Sep 28 '09 at 8:45
It can be useful in implementing something like the command pattern although many people would use boost::function to hide the raw member pointer mechanics.
– CB Bailey
Sep 28 '09 at 8:45
Thanks for the comment. Just after so many years of programing I've seen it used all over the place. I just consider passing a object cleaner and simpler.
– Chad
Sep 28 '09 at 8:56
Thanks for the comment. Just after so many years of programing I've seen it used all over the place. I just consider passing a object cleaner and simpler.
– Chad
Sep 28 '09 at 8:56
7
7
Why do you allocate that dog dynamically? You then have to manually delete the object, too. This looks a lot like you're coming from Java, C# or some other comparable language and still fight with C++. A plain automatic object (
Dog dog;
) is more likely what you want.– sbi
Sep 28 '09 at 9:18
Why do you allocate that dog dynamically? You then have to manually delete the object, too. This looks a lot like you're coming from Java, C# or some other comparable language and still fight with C++. A plain automatic object (
Dog dog;
) is more likely what you want.– sbi
Sep 28 '09 at 9:18
1
1
@Chad: I would mostly agree but there are times where passing a reference would be more costly. Consider a loop that is iterating over some type of data (parsing, calculation, etc..) than being able to call a function based on some if/else calculations imposes a cost where just calling the pointed too function could avoid such if/then/else checks if these checks could be done before entering the loop.
– Eric
Oct 25 '12 at 18:04
@Chad: I would mostly agree but there are times where passing a reference would be more costly. Consider a loop that is iterating over some type of data (parsing, calculation, etc..) than being able to call a function based on some if/else calculations imposes a cost where just calling the pointed too function could avoid such if/then/else checks if these checks could be done before entering the loop.
– Eric
Oct 25 '12 at 18:04
|
show 1 more comment
9 Answers
9
active
oldest
votes
Read this for detail :
// 1 define a function pointer and initialize to NULL
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
// Calling Function using Function Pointer
(*this.*pt2ConstMember)(12, 'a', 'b');
17
Surprising that they decided that this:*this.*pt2Member
would work.*
has higher precedence over.*
... Personally, I would still have writtenthis->*pt2Member
, that's one less operator.
– Alexis Wilke
Feb 17 '14 at 3:51
5
Why do you have to initializept2ConstMember
toNULL
?
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
@AlexisWilke why is it surprising? For direct objects (not pointers) it is(object.*method_pointer)
, so we want the*
to have greater priority.
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
20
What the hell isthis
doing outside method? Can you explain this more? Maybe a code that uses actual instance ofTMyClass
?
– Tomáš Zato
Oct 8 '15 at 14:53
@TomášZato, if I'm not mistaken (and I might be),this
is just being used to demonstrate that whatever you apply.*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.
– c1moore
Jan 31 '18 at 23:15
|
show 1 more comment
How do I obtain a function pointer for a class member function, and later call that member function with a specific object?
It's easiest to start with a typedef
. For a member function, you add the classname in the type declaration:
typedef void(Dog::*BarkFunction)(void);
Then to invoke the method, you use the ->*
operator:
(pDog->*pBark)();
Also, if possible, I’d like to invoke the constructor via a pointer as well. Is this possible, and if so, what is the preferred way to do this?
I don't believe you can work with constructors like this - ctors and dtors are special. The normal way to achieve that sort of thing would be using a factory method, which is basically just a static function that calls the constructor for you. See the code below for an example.
I have modified your code to do basically what you describe. There's some caveats below.
#include <iostream>
class Animal
{
public:
typedef Animal*(*NewAnimalFunction)(void);
virtual void makeNoise()
{
std::cout << "M00f!" << std::endl;
}
};
class Dog : public Animal
{
public:
typedef void(Dog::*BarkFunction)(void);
typedef Dog*(*NewDogFunction)(void);
Dog () {}
static Dog* newDog()
{
return new Dog;
}
virtual void makeNoise ()
{
std::cout << "Woof!" << std::endl;
}
};
int main(int argc, char* argv)
{
// Call member function via method pointer
Dog* pDog = new Dog ();
Dog::BarkFunction pBark = &Dog::makeNoise;
(pDog->*pBark)();
// Construct instance via factory method
Dog::NewDogFunction pNew = &Dog::newDog;
Animal* pAnimal = (*pNew)();
pAnimal->makeNoise();
return 0;
}
Now although you can normally use a Dog*
in the place of an Animal*
thanks to the magic of polymorphism, the type of a function pointer does not follow the lookup rules of class hierarchy. So an Animal method pointer is not compatible with a Dog method pointer, in other words you can't assign a Dog* (*)()
to a variable of type Animal* (*)()
.
The static newDog
method is a simple example of a factory, which simply creates and returns new instances. Being a static function, it has a regular typedef
(with no class qualifier).
Having answered the above, I do wonder if there's not a better way of achieving what you need. There's a few specific scenarios where you would do this sort of thing, but you might find there's other patterns that work better for your problem. If you describe in more general terms what you are trying to achieve, the hive-mind may prove even more useful!
Related to the above, you will no doubt find the Boost bind library and other related modules very useful.
7
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of->*
before, but now I hope I'll never need it :)
– Thomas
Sep 28 '09 at 11:37
add a comment |
I don't think anyone has explained here that one issue is that you need "member pointers" rather than normal function pointers.
Member pointers to functions are not simply function pointers. In implementation terms, the compiler cannot use a simple function address because, in general, you don't know the address to call until you know which object to dereference for (think virtual functions). You also need to know the object in order to provide the this
implicit parameter, of course.
Having said that you need them, now I'll say that you really need to avoid them. Seriously, member pointers are a pain. It is much more sane to look at object-oriented design patterns that achieve the same goal, or to use a boost::function
or whatever as mentioned above - assuming you get to make that choice, that is.
If you are supplying that function pointer to existing code, so you really need a simple function pointer, you should write a function as a static member of the class. A static member function doesn't understand this
, so you'll need to pass the object in as an explicit parameter. There was once a not-that-unusual idiom along these lines for working with old C code that needs function pointers
class myclass
{
public:
virtual void myrealmethod () = 0;
static void myfunction (myclass *p);
}
void myclass::myfunction (myclass *p)
{
p->myrealmethod ();
}
Since myfunction
is really just a normal function (scope issues aside), a function pointer can be found in the normal C way.
EDIT - this kind of method is called a "class method" or a "static member function". The main difference from a non-member function is that, if you reference it from outside the class, you must specify the scope using the ::
scope resolution operator. For example, to get the function pointer, use &myclass::myfunction
and to call it use myclass::myfunction (arg);
.
This kind of thing is fairly common when using the old Win32 APIs, which were originally designed for C rather than C++. Of course in that case, the parameter is normally LPARAM or similar rather than a pointer, and some casting is needed.
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
2
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
add a comment |
typedef void (Dog::*memfun)();
memfun doSomething = &Dog::bark;
....
(pDog->*doSomething)(); // if pDog is a pointer
// (pDog.*doSomething)(); // if pDog is a reference
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
2
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
add a comment |
I came here to learn how to create a function pointer (not a method pointer) from a method but none of the answers here provide a solution. So I thought about it and found a nice solution which I think is worth sharing:
template <class T> struct MethodHelper;
template <class C, class Ret, class... Args> struct MethodHelper<Ret(C::*)(Args...)> {
using T = Ret (C::*)(Args...);
template <T m> static Ret call(C* object, Args... args) {
return (object->*m)(args...);
}
};
#define METHOD_FP(m) MethodHelper<decltype(m)>::call<m>
So for your example you would now do:
Dog dog;
using BarkFunction = void (*)(Dog*);
BarkFunction bark = METHOD_FP(&Dog::bark);
(*bark)(&dog); // or simply bark(&dog)
add a comment |
Minimal runnable example
#include <cassert>
class C {
public:
int i;
C(int i) : i(i) {}
int m(int j) { return this->i + j; }
};
int main() {
// Get a method pointer.
int (C::*p)(int) = &C::m;
// Create a test object.
C c(1);
C *cp = &c;
// Operator .*
assert((c.*p)(2) == 3);
// Operator ->*
assert((cp->*p)(2) == 3);
}
You cannot change the order of the parenthesis or omit them. The following do not work:
c.*p(2)
c.*(p)(2)
C++11 standard
.*
and ->*
are a singe operators introduced in C++ for this purpose, and not present in C.
C++11 N3337 standard draft:
- 2.13 "Operators and punctuators" has a list of all operators, which contains
.*
and->*
. - 5.5 "Pointer-to-member operators" explains what they do
add a comment |
Reason why you cannot use function pointers to call member functions is that
ordinary function pointers are usually just the memory address of the function.
To call a member function, you need to know two things:
- Which member function to call
- Which instance should be used (whose member function)
Ordinary function pointers cannot store both. C++ member function pointers are used
to store a), which is why you need to specify the instance explicitly when calling a member function pointer.
1
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
add a comment |
A function pointer to a class member is a problem that is really suited to using boost::function. Small example:
#include <boost/function.hpp>
#include <iostream>
class Dog
{
public:
Dog (int i) : tmp(i) {}
void bark ()
{
std::cout << "woof: " << tmp << std::endl;
}
private:
int tmp;
};
int main()
{
Dog* pDog1 = new Dog (1);
Dog* pDog2 = new Dog (2);
//BarkFunction pBark = &Dog::bark;
boost::function<void (Dog*)> f1 = &Dog::bark;
f1(pDog1);
f1(pDog2);
}
add a comment |
To create a new object you can either use placement new, as mentioned above, or have your class implement a clone() method that creates a copy of the object. You can then call this clone method using a member function pointer as explained above to create new instances of the object. The advantage of clone is that sometimes you may be working with a pointer to a base class where you don't know the type of the object. In this case a clone() method can be easier to use. Also, clone() will let you copy the state of the object if that is what you want.
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1485983%2fcalling-c-class-methods-via-a-function-pointer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
Read this for detail :
// 1 define a function pointer and initialize to NULL
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
// Calling Function using Function Pointer
(*this.*pt2ConstMember)(12, 'a', 'b');
17
Surprising that they decided that this:*this.*pt2Member
would work.*
has higher precedence over.*
... Personally, I would still have writtenthis->*pt2Member
, that's one less operator.
– Alexis Wilke
Feb 17 '14 at 3:51
5
Why do you have to initializept2ConstMember
toNULL
?
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
@AlexisWilke why is it surprising? For direct objects (not pointers) it is(object.*method_pointer)
, so we want the*
to have greater priority.
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
20
What the hell isthis
doing outside method? Can you explain this more? Maybe a code that uses actual instance ofTMyClass
?
– Tomáš Zato
Oct 8 '15 at 14:53
@TomášZato, if I'm not mistaken (and I might be),this
is just being used to demonstrate that whatever you apply.*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.
– c1moore
Jan 31 '18 at 23:15
|
show 1 more comment
Read this for detail :
// 1 define a function pointer and initialize to NULL
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
// Calling Function using Function Pointer
(*this.*pt2ConstMember)(12, 'a', 'b');
17
Surprising that they decided that this:*this.*pt2Member
would work.*
has higher precedence over.*
... Personally, I would still have writtenthis->*pt2Member
, that's one less operator.
– Alexis Wilke
Feb 17 '14 at 3:51
5
Why do you have to initializept2ConstMember
toNULL
?
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
@AlexisWilke why is it surprising? For direct objects (not pointers) it is(object.*method_pointer)
, so we want the*
to have greater priority.
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
20
What the hell isthis
doing outside method? Can you explain this more? Maybe a code that uses actual instance ofTMyClass
?
– Tomáš Zato
Oct 8 '15 at 14:53
@TomášZato, if I'm not mistaken (and I might be),this
is just being used to demonstrate that whatever you apply.*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.
– c1moore
Jan 31 '18 at 23:15
|
show 1 more comment
Read this for detail :
// 1 define a function pointer and initialize to NULL
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
// Calling Function using Function Pointer
(*this.*pt2ConstMember)(12, 'a', 'b');
Read this for detail :
// 1 define a function pointer and initialize to NULL
int (TMyClass::*pt2ConstMember)(float, char, char) const = NULL;
// C++
class TMyClass
{
public:
int DoIt(float a, char b, char c){ cout << "TMyClass::DoIt"<< endl; return a+b+c;};
int DoMore(float a, char b, char c) const
{ cout << "TMyClass::DoMore" << endl; return a-b+c; };
/* more of TMyClass */
};
pt2ConstMember = &TMyClass::DoIt; // note: <pt2Member> may also legally point to &DoMore
// Calling Function using Function Pointer
(*this.*pt2ConstMember)(12, 'a', 'b');
edited Dec 16 '18 at 20:57
Zoe
13.2k85386
13.2k85386
answered Sep 28 '09 at 10:04
SatbirSatbir
4,23663148
4,23663148
17
Surprising that they decided that this:*this.*pt2Member
would work.*
has higher precedence over.*
... Personally, I would still have writtenthis->*pt2Member
, that's one less operator.
– Alexis Wilke
Feb 17 '14 at 3:51
5
Why do you have to initializept2ConstMember
toNULL
?
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
@AlexisWilke why is it surprising? For direct objects (not pointers) it is(object.*method_pointer)
, so we want the*
to have greater priority.
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
20
What the hell isthis
doing outside method? Can you explain this more? Maybe a code that uses actual instance ofTMyClass
?
– Tomáš Zato
Oct 8 '15 at 14:53
@TomášZato, if I'm not mistaken (and I might be),this
is just being used to demonstrate that whatever you apply.*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.
– c1moore
Jan 31 '18 at 23:15
|
show 1 more comment
17
Surprising that they decided that this:*this.*pt2Member
would work.*
has higher precedence over.*
... Personally, I would still have writtenthis->*pt2Member
, that's one less operator.
– Alexis Wilke
Feb 17 '14 at 3:51
5
Why do you have to initializept2ConstMember
toNULL
?
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
@AlexisWilke why is it surprising? For direct objects (not pointers) it is(object.*method_pointer)
, so we want the*
to have greater priority.
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
20
What the hell isthis
doing outside method? Can you explain this more? Maybe a code that uses actual instance ofTMyClass
?
– Tomáš Zato
Oct 8 '15 at 14:53
@TomášZato, if I'm not mistaken (and I might be),this
is just being used to demonstrate that whatever you apply.*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.
– c1moore
Jan 31 '18 at 23:15
17
17
Surprising that they decided that this:
*this.*pt2Member
would work. *
has higher precedence over .*
... Personally, I would still have written this->*pt2Member
, that's one less operator.– Alexis Wilke
Feb 17 '14 at 3:51
Surprising that they decided that this:
*this.*pt2Member
would work. *
has higher precedence over .*
... Personally, I would still have written this->*pt2Member
, that's one less operator.– Alexis Wilke
Feb 17 '14 at 3:51
5
5
Why do you have to initialize
pt2ConstMember
to NULL
?– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
Why do you have to initialize
pt2ConstMember
to NULL
?– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:00
@AlexisWilke why is it surprising? For direct objects (not pointers) it is
(object.*method_pointer)
, so we want the *
to have greater priority.– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
@AlexisWilke why is it surprising? For direct objects (not pointers) it is
(object.*method_pointer)
, so we want the *
to have greater priority.– Ciro Santilli 新疆改造中心 六四事件 法轮功
Jul 1 '15 at 9:02
20
20
What the hell is
this
doing outside method? Can you explain this more? Maybe a code that uses actual instance of TMyClass
?– Tomáš Zato
Oct 8 '15 at 14:53
What the hell is
this
doing outside method? Can you explain this more? Maybe a code that uses actual instance of TMyClass
?– Tomáš Zato
Oct 8 '15 at 14:53
@TomášZato, if I'm not mistaken (and I might be),
this
is just being used to demonstrate that whatever you apply .*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.– c1moore
Jan 31 '18 at 23:15
@TomášZato, if I'm not mistaken (and I might be),
this
is just being used to demonstrate that whatever you apply .*
to should be a pointer to an instance of the (sub)class. However this is new syntax to me I'm only guessing based on other answers and resources linked here. I'm suggesting an edit to make that more clear.– c1moore
Jan 31 '18 at 23:15
|
show 1 more comment
How do I obtain a function pointer for a class member function, and later call that member function with a specific object?
It's easiest to start with a typedef
. For a member function, you add the classname in the type declaration:
typedef void(Dog::*BarkFunction)(void);
Then to invoke the method, you use the ->*
operator:
(pDog->*pBark)();
Also, if possible, I’d like to invoke the constructor via a pointer as well. Is this possible, and if so, what is the preferred way to do this?
I don't believe you can work with constructors like this - ctors and dtors are special. The normal way to achieve that sort of thing would be using a factory method, which is basically just a static function that calls the constructor for you. See the code below for an example.
I have modified your code to do basically what you describe. There's some caveats below.
#include <iostream>
class Animal
{
public:
typedef Animal*(*NewAnimalFunction)(void);
virtual void makeNoise()
{
std::cout << "M00f!" << std::endl;
}
};
class Dog : public Animal
{
public:
typedef void(Dog::*BarkFunction)(void);
typedef Dog*(*NewDogFunction)(void);
Dog () {}
static Dog* newDog()
{
return new Dog;
}
virtual void makeNoise ()
{
std::cout << "Woof!" << std::endl;
}
};
int main(int argc, char* argv)
{
// Call member function via method pointer
Dog* pDog = new Dog ();
Dog::BarkFunction pBark = &Dog::makeNoise;
(pDog->*pBark)();
// Construct instance via factory method
Dog::NewDogFunction pNew = &Dog::newDog;
Animal* pAnimal = (*pNew)();
pAnimal->makeNoise();
return 0;
}
Now although you can normally use a Dog*
in the place of an Animal*
thanks to the magic of polymorphism, the type of a function pointer does not follow the lookup rules of class hierarchy. So an Animal method pointer is not compatible with a Dog method pointer, in other words you can't assign a Dog* (*)()
to a variable of type Animal* (*)()
.
The static newDog
method is a simple example of a factory, which simply creates and returns new instances. Being a static function, it has a regular typedef
(with no class qualifier).
Having answered the above, I do wonder if there's not a better way of achieving what you need. There's a few specific scenarios where you would do this sort of thing, but you might find there's other patterns that work better for your problem. If you describe in more general terms what you are trying to achieve, the hive-mind may prove even more useful!
Related to the above, you will no doubt find the Boost bind library and other related modules very useful.
7
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of->*
before, but now I hope I'll never need it :)
– Thomas
Sep 28 '09 at 11:37
add a comment |
How do I obtain a function pointer for a class member function, and later call that member function with a specific object?
It's easiest to start with a typedef
. For a member function, you add the classname in the type declaration:
typedef void(Dog::*BarkFunction)(void);
Then to invoke the method, you use the ->*
operator:
(pDog->*pBark)();
Also, if possible, I’d like to invoke the constructor via a pointer as well. Is this possible, and if so, what is the preferred way to do this?
I don't believe you can work with constructors like this - ctors and dtors are special. The normal way to achieve that sort of thing would be using a factory method, which is basically just a static function that calls the constructor for you. See the code below for an example.
I have modified your code to do basically what you describe. There's some caveats below.
#include <iostream>
class Animal
{
public:
typedef Animal*(*NewAnimalFunction)(void);
virtual void makeNoise()
{
std::cout << "M00f!" << std::endl;
}
};
class Dog : public Animal
{
public:
typedef void(Dog::*BarkFunction)(void);
typedef Dog*(*NewDogFunction)(void);
Dog () {}
static Dog* newDog()
{
return new Dog;
}
virtual void makeNoise ()
{
std::cout << "Woof!" << std::endl;
}
};
int main(int argc, char* argv)
{
// Call member function via method pointer
Dog* pDog = new Dog ();
Dog::BarkFunction pBark = &Dog::makeNoise;
(pDog->*pBark)();
// Construct instance via factory method
Dog::NewDogFunction pNew = &Dog::newDog;
Animal* pAnimal = (*pNew)();
pAnimal->makeNoise();
return 0;
}
Now although you can normally use a Dog*
in the place of an Animal*
thanks to the magic of polymorphism, the type of a function pointer does not follow the lookup rules of class hierarchy. So an Animal method pointer is not compatible with a Dog method pointer, in other words you can't assign a Dog* (*)()
to a variable of type Animal* (*)()
.
The static newDog
method is a simple example of a factory, which simply creates and returns new instances. Being a static function, it has a regular typedef
(with no class qualifier).
Having answered the above, I do wonder if there's not a better way of achieving what you need. There's a few specific scenarios where you would do this sort of thing, but you might find there's other patterns that work better for your problem. If you describe in more general terms what you are trying to achieve, the hive-mind may prove even more useful!
Related to the above, you will no doubt find the Boost bind library and other related modules very useful.
7
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of->*
before, but now I hope I'll never need it :)
– Thomas
Sep 28 '09 at 11:37
add a comment |
How do I obtain a function pointer for a class member function, and later call that member function with a specific object?
It's easiest to start with a typedef
. For a member function, you add the classname in the type declaration:
typedef void(Dog::*BarkFunction)(void);
Then to invoke the method, you use the ->*
operator:
(pDog->*pBark)();
Also, if possible, I’d like to invoke the constructor via a pointer as well. Is this possible, and if so, what is the preferred way to do this?
I don't believe you can work with constructors like this - ctors and dtors are special. The normal way to achieve that sort of thing would be using a factory method, which is basically just a static function that calls the constructor for you. See the code below for an example.
I have modified your code to do basically what you describe. There's some caveats below.
#include <iostream>
class Animal
{
public:
typedef Animal*(*NewAnimalFunction)(void);
virtual void makeNoise()
{
std::cout << "M00f!" << std::endl;
}
};
class Dog : public Animal
{
public:
typedef void(Dog::*BarkFunction)(void);
typedef Dog*(*NewDogFunction)(void);
Dog () {}
static Dog* newDog()
{
return new Dog;
}
virtual void makeNoise ()
{
std::cout << "Woof!" << std::endl;
}
};
int main(int argc, char* argv)
{
// Call member function via method pointer
Dog* pDog = new Dog ();
Dog::BarkFunction pBark = &Dog::makeNoise;
(pDog->*pBark)();
// Construct instance via factory method
Dog::NewDogFunction pNew = &Dog::newDog;
Animal* pAnimal = (*pNew)();
pAnimal->makeNoise();
return 0;
}
Now although you can normally use a Dog*
in the place of an Animal*
thanks to the magic of polymorphism, the type of a function pointer does not follow the lookup rules of class hierarchy. So an Animal method pointer is not compatible with a Dog method pointer, in other words you can't assign a Dog* (*)()
to a variable of type Animal* (*)()
.
The static newDog
method is a simple example of a factory, which simply creates and returns new instances. Being a static function, it has a regular typedef
(with no class qualifier).
Having answered the above, I do wonder if there's not a better way of achieving what you need. There's a few specific scenarios where you would do this sort of thing, but you might find there's other patterns that work better for your problem. If you describe in more general terms what you are trying to achieve, the hive-mind may prove even more useful!
Related to the above, you will no doubt find the Boost bind library and other related modules very useful.
How do I obtain a function pointer for a class member function, and later call that member function with a specific object?
It's easiest to start with a typedef
. For a member function, you add the classname in the type declaration:
typedef void(Dog::*BarkFunction)(void);
Then to invoke the method, you use the ->*
operator:
(pDog->*pBark)();
Also, if possible, I’d like to invoke the constructor via a pointer as well. Is this possible, and if so, what is the preferred way to do this?
I don't believe you can work with constructors like this - ctors and dtors are special. The normal way to achieve that sort of thing would be using a factory method, which is basically just a static function that calls the constructor for you. See the code below for an example.
I have modified your code to do basically what you describe. There's some caveats below.
#include <iostream>
class Animal
{
public:
typedef Animal*(*NewAnimalFunction)(void);
virtual void makeNoise()
{
std::cout << "M00f!" << std::endl;
}
};
class Dog : public Animal
{
public:
typedef void(Dog::*BarkFunction)(void);
typedef Dog*(*NewDogFunction)(void);
Dog () {}
static Dog* newDog()
{
return new Dog;
}
virtual void makeNoise ()
{
std::cout << "Woof!" << std::endl;
}
};
int main(int argc, char* argv)
{
// Call member function via method pointer
Dog* pDog = new Dog ();
Dog::BarkFunction pBark = &Dog::makeNoise;
(pDog->*pBark)();
// Construct instance via factory method
Dog::NewDogFunction pNew = &Dog::newDog;
Animal* pAnimal = (*pNew)();
pAnimal->makeNoise();
return 0;
}
Now although you can normally use a Dog*
in the place of an Animal*
thanks to the magic of polymorphism, the type of a function pointer does not follow the lookup rules of class hierarchy. So an Animal method pointer is not compatible with a Dog method pointer, in other words you can't assign a Dog* (*)()
to a variable of type Animal* (*)()
.
The static newDog
method is a simple example of a factory, which simply creates and returns new instances. Being a static function, it has a regular typedef
(with no class qualifier).
Having answered the above, I do wonder if there's not a better way of achieving what you need. There's a few specific scenarios where you would do this sort of thing, but you might find there's other patterns that work better for your problem. If you describe in more general terms what you are trying to achieve, the hive-mind may prove even more useful!
Related to the above, you will no doubt find the Boost bind library and other related modules very useful.
answered Sep 28 '09 at 10:20
gavinbgavinb
14.6k13648
14.6k13648
7
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of->*
before, but now I hope I'll never need it :)
– Thomas
Sep 28 '09 at 11:37
add a comment |
7
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of->*
before, but now I hope I'll never need it :)
– Thomas
Sep 28 '09 at 11:37
7
7
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of
->*
before, but now I hope I'll never need it :)– Thomas
Sep 28 '09 at 11:37
I have used C++ for over 10 years, and keep learning something new on a regular basis. I'd never heard of
->*
before, but now I hope I'll never need it :)– Thomas
Sep 28 '09 at 11:37
add a comment |
I don't think anyone has explained here that one issue is that you need "member pointers" rather than normal function pointers.
Member pointers to functions are not simply function pointers. In implementation terms, the compiler cannot use a simple function address because, in general, you don't know the address to call until you know which object to dereference for (think virtual functions). You also need to know the object in order to provide the this
implicit parameter, of course.
Having said that you need them, now I'll say that you really need to avoid them. Seriously, member pointers are a pain. It is much more sane to look at object-oriented design patterns that achieve the same goal, or to use a boost::function
or whatever as mentioned above - assuming you get to make that choice, that is.
If you are supplying that function pointer to existing code, so you really need a simple function pointer, you should write a function as a static member of the class. A static member function doesn't understand this
, so you'll need to pass the object in as an explicit parameter. There was once a not-that-unusual idiom along these lines for working with old C code that needs function pointers
class myclass
{
public:
virtual void myrealmethod () = 0;
static void myfunction (myclass *p);
}
void myclass::myfunction (myclass *p)
{
p->myrealmethod ();
}
Since myfunction
is really just a normal function (scope issues aside), a function pointer can be found in the normal C way.
EDIT - this kind of method is called a "class method" or a "static member function". The main difference from a non-member function is that, if you reference it from outside the class, you must specify the scope using the ::
scope resolution operator. For example, to get the function pointer, use &myclass::myfunction
and to call it use myclass::myfunction (arg);
.
This kind of thing is fairly common when using the old Win32 APIs, which were originally designed for C rather than C++. Of course in that case, the parameter is normally LPARAM or similar rather than a pointer, and some casting is needed.
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
2
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
add a comment |
I don't think anyone has explained here that one issue is that you need "member pointers" rather than normal function pointers.
Member pointers to functions are not simply function pointers. In implementation terms, the compiler cannot use a simple function address because, in general, you don't know the address to call until you know which object to dereference for (think virtual functions). You also need to know the object in order to provide the this
implicit parameter, of course.
Having said that you need them, now I'll say that you really need to avoid them. Seriously, member pointers are a pain. It is much more sane to look at object-oriented design patterns that achieve the same goal, or to use a boost::function
or whatever as mentioned above - assuming you get to make that choice, that is.
If you are supplying that function pointer to existing code, so you really need a simple function pointer, you should write a function as a static member of the class. A static member function doesn't understand this
, so you'll need to pass the object in as an explicit parameter. There was once a not-that-unusual idiom along these lines for working with old C code that needs function pointers
class myclass
{
public:
virtual void myrealmethod () = 0;
static void myfunction (myclass *p);
}
void myclass::myfunction (myclass *p)
{
p->myrealmethod ();
}
Since myfunction
is really just a normal function (scope issues aside), a function pointer can be found in the normal C way.
EDIT - this kind of method is called a "class method" or a "static member function". The main difference from a non-member function is that, if you reference it from outside the class, you must specify the scope using the ::
scope resolution operator. For example, to get the function pointer, use &myclass::myfunction
and to call it use myclass::myfunction (arg);
.
This kind of thing is fairly common when using the old Win32 APIs, which were originally designed for C rather than C++. Of course in that case, the parameter is normally LPARAM or similar rather than a pointer, and some casting is needed.
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
2
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
add a comment |
I don't think anyone has explained here that one issue is that you need "member pointers" rather than normal function pointers.
Member pointers to functions are not simply function pointers. In implementation terms, the compiler cannot use a simple function address because, in general, you don't know the address to call until you know which object to dereference for (think virtual functions). You also need to know the object in order to provide the this
implicit parameter, of course.
Having said that you need them, now I'll say that you really need to avoid them. Seriously, member pointers are a pain. It is much more sane to look at object-oriented design patterns that achieve the same goal, or to use a boost::function
or whatever as mentioned above - assuming you get to make that choice, that is.
If you are supplying that function pointer to existing code, so you really need a simple function pointer, you should write a function as a static member of the class. A static member function doesn't understand this
, so you'll need to pass the object in as an explicit parameter. There was once a not-that-unusual idiom along these lines for working with old C code that needs function pointers
class myclass
{
public:
virtual void myrealmethod () = 0;
static void myfunction (myclass *p);
}
void myclass::myfunction (myclass *p)
{
p->myrealmethod ();
}
Since myfunction
is really just a normal function (scope issues aside), a function pointer can be found in the normal C way.
EDIT - this kind of method is called a "class method" or a "static member function". The main difference from a non-member function is that, if you reference it from outside the class, you must specify the scope using the ::
scope resolution operator. For example, to get the function pointer, use &myclass::myfunction
and to call it use myclass::myfunction (arg);
.
This kind of thing is fairly common when using the old Win32 APIs, which were originally designed for C rather than C++. Of course in that case, the parameter is normally LPARAM or similar rather than a pointer, and some casting is needed.
I don't think anyone has explained here that one issue is that you need "member pointers" rather than normal function pointers.
Member pointers to functions are not simply function pointers. In implementation terms, the compiler cannot use a simple function address because, in general, you don't know the address to call until you know which object to dereference for (think virtual functions). You also need to know the object in order to provide the this
implicit parameter, of course.
Having said that you need them, now I'll say that you really need to avoid them. Seriously, member pointers are a pain. It is much more sane to look at object-oriented design patterns that achieve the same goal, or to use a boost::function
or whatever as mentioned above - assuming you get to make that choice, that is.
If you are supplying that function pointer to existing code, so you really need a simple function pointer, you should write a function as a static member of the class. A static member function doesn't understand this
, so you'll need to pass the object in as an explicit parameter. There was once a not-that-unusual idiom along these lines for working with old C code that needs function pointers
class myclass
{
public:
virtual void myrealmethod () = 0;
static void myfunction (myclass *p);
}
void myclass::myfunction (myclass *p)
{
p->myrealmethod ();
}
Since myfunction
is really just a normal function (scope issues aside), a function pointer can be found in the normal C way.
EDIT - this kind of method is called a "class method" or a "static member function". The main difference from a non-member function is that, if you reference it from outside the class, you must specify the scope using the ::
scope resolution operator. For example, to get the function pointer, use &myclass::myfunction
and to call it use myclass::myfunction (arg);
.
This kind of thing is fairly common when using the old Win32 APIs, which were originally designed for C rather than C++. Of course in that case, the parameter is normally LPARAM or similar rather than a pointer, and some casting is needed.
edited Jun 7 '17 at 11:41
Ziezi
4,91132638
4,91132638
answered Sep 28 '09 at 14:54
Steve314Steve314
21.8k1049110
21.8k1049110
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
2
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
add a comment |
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
2
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
'myfunction' is not a normmal function if by normal you mean a C style function. 'myfunction' is more accurately called a method of myclass. Methods of a class are not like normal functions in that they have something a C style function does not which is the 'this' pointer.
– Eric
Oct 25 '12 at 17:57
2
2
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
advising to use boost is draconian. There are practical good reasons for using method pointers. I don't mind the mention of boost as an alternative but hate when someone says someone else should use it without knowing all the facts. Boost comes at a cost! And if this is an embedded platform then it may not be a choice that's possible. Beyond this, I really like your write up.
– Eric
Oct 25 '12 at 18:10
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - On your second point, I didn't intend to say "thou shalt use Boost", and in fact I've never used Boost myself. The intention (as far as I know it after 3 years) was that people should look for alternatives, and to list a few possibilities. "Or whatever" indicates that a list isn't meant to be exhaustive. Member pointers have a cost in readability. Their concise source representation can also disguise run-time costs - in particular a member pointer to a method must cope with both non-virtual and virtual methods, and must know which.
– Steve314
Oct 25 '12 at 22:09
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - Not only that, but these issues are a reason for non-portability with member pointers - Visual C++, at least in the past, needed some extra clues about how to represent member pointer types. I'd use the static function approach for an embedded system - the representation of a pointer is the same as any other function pointer, the costs are obvious, and there's no portability issue. And the call wrapped by the static member function knows (at compile time) whether the call is virtual or not - no run-time checks needed beyond the usual vtable lookups for virtual methods.
– Steve314
Oct 25 '12 at 22:15
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
@Eric - on your first point - I'm aware that a static member function isn't exactly the same as a C-style function (hence "scope issues aside"), but I probably should have included the name.
– Steve314
Oct 25 '12 at 22:23
add a comment |
typedef void (Dog::*memfun)();
memfun doSomething = &Dog::bark;
....
(pDog->*doSomething)(); // if pDog is a pointer
// (pDog.*doSomething)(); // if pDog is a reference
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
2
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
add a comment |
typedef void (Dog::*memfun)();
memfun doSomething = &Dog::bark;
....
(pDog->*doSomething)(); // if pDog is a pointer
// (pDog.*doSomething)(); // if pDog is a reference
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
2
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
add a comment |
typedef void (Dog::*memfun)();
memfun doSomething = &Dog::bark;
....
(pDog->*doSomething)(); // if pDog is a pointer
// (pDog.*doSomething)(); // if pDog is a reference
typedef void (Dog::*memfun)();
memfun doSomething = &Dog::bark;
....
(pDog->*doSomething)(); // if pDog is a pointer
// (pDog.*doSomething)(); // if pDog is a reference
edited Sep 28 '09 at 11:34
answered Sep 28 '09 at 8:33
AraKAraK
65.5k30154225
65.5k30154225
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
2
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
add a comment |
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
2
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
To be honest I have no compiler between my hands and I just hate the syntax of member function pointers :(
– AraK
Sep 28 '09 at 8:37
2
2
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
Should be: (pDog->*doSomething)(); // if pDog is a pointer // (pDog.*doSomething)(); // if pDog is a reference as () operator has higher priority then ->* and .*.
– Tomek
Sep 28 '09 at 9:13
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
@Tomek Thanks very much :)
– AraK
Sep 28 '09 at 11:34
add a comment |
I came here to learn how to create a function pointer (not a method pointer) from a method but none of the answers here provide a solution. So I thought about it and found a nice solution which I think is worth sharing:
template <class T> struct MethodHelper;
template <class C, class Ret, class... Args> struct MethodHelper<Ret(C::*)(Args...)> {
using T = Ret (C::*)(Args...);
template <T m> static Ret call(C* object, Args... args) {
return (object->*m)(args...);
}
};
#define METHOD_FP(m) MethodHelper<decltype(m)>::call<m>
So for your example you would now do:
Dog dog;
using BarkFunction = void (*)(Dog*);
BarkFunction bark = METHOD_FP(&Dog::bark);
(*bark)(&dog); // or simply bark(&dog)
add a comment |
I came here to learn how to create a function pointer (not a method pointer) from a method but none of the answers here provide a solution. So I thought about it and found a nice solution which I think is worth sharing:
template <class T> struct MethodHelper;
template <class C, class Ret, class... Args> struct MethodHelper<Ret(C::*)(Args...)> {
using T = Ret (C::*)(Args...);
template <T m> static Ret call(C* object, Args... args) {
return (object->*m)(args...);
}
};
#define METHOD_FP(m) MethodHelper<decltype(m)>::call<m>
So for your example you would now do:
Dog dog;
using BarkFunction = void (*)(Dog*);
BarkFunction bark = METHOD_FP(&Dog::bark);
(*bark)(&dog); // or simply bark(&dog)
add a comment |
I came here to learn how to create a function pointer (not a method pointer) from a method but none of the answers here provide a solution. So I thought about it and found a nice solution which I think is worth sharing:
template <class T> struct MethodHelper;
template <class C, class Ret, class... Args> struct MethodHelper<Ret(C::*)(Args...)> {
using T = Ret (C::*)(Args...);
template <T m> static Ret call(C* object, Args... args) {
return (object->*m)(args...);
}
};
#define METHOD_FP(m) MethodHelper<decltype(m)>::call<m>
So for your example you would now do:
Dog dog;
using BarkFunction = void (*)(Dog*);
BarkFunction bark = METHOD_FP(&Dog::bark);
(*bark)(&dog); // or simply bark(&dog)
I came here to learn how to create a function pointer (not a method pointer) from a method but none of the answers here provide a solution. So I thought about it and found a nice solution which I think is worth sharing:
template <class T> struct MethodHelper;
template <class C, class Ret, class... Args> struct MethodHelper<Ret(C::*)(Args...)> {
using T = Ret (C::*)(Args...);
template <T m> static Ret call(C* object, Args... args) {
return (object->*m)(args...);
}
};
#define METHOD_FP(m) MethodHelper<decltype(m)>::call<m>
So for your example you would now do:
Dog dog;
using BarkFunction = void (*)(Dog*);
BarkFunction bark = METHOD_FP(&Dog::bark);
(*bark)(&dog); // or simply bark(&dog)
edited Aug 3 '16 at 10:11
answered Jun 18 '16 at 10:15
eyelasheyelash
1,3201519
1,3201519
add a comment |
add a comment |
Minimal runnable example
#include <cassert>
class C {
public:
int i;
C(int i) : i(i) {}
int m(int j) { return this->i + j; }
};
int main() {
// Get a method pointer.
int (C::*p)(int) = &C::m;
// Create a test object.
C c(1);
C *cp = &c;
// Operator .*
assert((c.*p)(2) == 3);
// Operator ->*
assert((cp->*p)(2) == 3);
}
You cannot change the order of the parenthesis or omit them. The following do not work:
c.*p(2)
c.*(p)(2)
C++11 standard
.*
and ->*
are a singe operators introduced in C++ for this purpose, and not present in C.
C++11 N3337 standard draft:
- 2.13 "Operators and punctuators" has a list of all operators, which contains
.*
and->*
. - 5.5 "Pointer-to-member operators" explains what they do
add a comment |
Minimal runnable example
#include <cassert>
class C {
public:
int i;
C(int i) : i(i) {}
int m(int j) { return this->i + j; }
};
int main() {
// Get a method pointer.
int (C::*p)(int) = &C::m;
// Create a test object.
C c(1);
C *cp = &c;
// Operator .*
assert((c.*p)(2) == 3);
// Operator ->*
assert((cp->*p)(2) == 3);
}
You cannot change the order of the parenthesis or omit them. The following do not work:
c.*p(2)
c.*(p)(2)
C++11 standard
.*
and ->*
are a singe operators introduced in C++ for this purpose, and not present in C.
C++11 N3337 standard draft:
- 2.13 "Operators and punctuators" has a list of all operators, which contains
.*
and->*
. - 5.5 "Pointer-to-member operators" explains what they do
add a comment |
Minimal runnable example
#include <cassert>
class C {
public:
int i;
C(int i) : i(i) {}
int m(int j) { return this->i + j; }
};
int main() {
// Get a method pointer.
int (C::*p)(int) = &C::m;
// Create a test object.
C c(1);
C *cp = &c;
// Operator .*
assert((c.*p)(2) == 3);
// Operator ->*
assert((cp->*p)(2) == 3);
}
You cannot change the order of the parenthesis or omit them. The following do not work:
c.*p(2)
c.*(p)(2)
C++11 standard
.*
and ->*
are a singe operators introduced in C++ for this purpose, and not present in C.
C++11 N3337 standard draft:
- 2.13 "Operators and punctuators" has a list of all operators, which contains
.*
and->*
. - 5.5 "Pointer-to-member operators" explains what they do
Minimal runnable example
#include <cassert>
class C {
public:
int i;
C(int i) : i(i) {}
int m(int j) { return this->i + j; }
};
int main() {
// Get a method pointer.
int (C::*p)(int) = &C::m;
// Create a test object.
C c(1);
C *cp = &c;
// Operator .*
assert((c.*p)(2) == 3);
// Operator ->*
assert((cp->*p)(2) == 3);
}
You cannot change the order of the parenthesis or omit them. The following do not work:
c.*p(2)
c.*(p)(2)
C++11 standard
.*
and ->*
are a singe operators introduced in C++ for this purpose, and not present in C.
C++11 N3337 standard draft:
- 2.13 "Operators and punctuators" has a list of all operators, which contains
.*
and->*
. - 5.5 "Pointer-to-member operators" explains what they do
edited Apr 5 '16 at 8:47
answered Jul 1 '15 at 9:06
Ciro Santilli 新疆改造中心 六四事件 法轮功Ciro Santilli 新疆改造中心 六四事件 法轮功
148k34560476
148k34560476
add a comment |
add a comment |
Reason why you cannot use function pointers to call member functions is that
ordinary function pointers are usually just the memory address of the function.
To call a member function, you need to know two things:
- Which member function to call
- Which instance should be used (whose member function)
Ordinary function pointers cannot store both. C++ member function pointers are used
to store a), which is why you need to specify the instance explicitly when calling a member function pointer.
1
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
add a comment |
Reason why you cannot use function pointers to call member functions is that
ordinary function pointers are usually just the memory address of the function.
To call a member function, you need to know two things:
- Which member function to call
- Which instance should be used (whose member function)
Ordinary function pointers cannot store both. C++ member function pointers are used
to store a), which is why you need to specify the instance explicitly when calling a member function pointer.
1
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
add a comment |
Reason why you cannot use function pointers to call member functions is that
ordinary function pointers are usually just the memory address of the function.
To call a member function, you need to know two things:
- Which member function to call
- Which instance should be used (whose member function)
Ordinary function pointers cannot store both. C++ member function pointers are used
to store a), which is why you need to specify the instance explicitly when calling a member function pointer.
Reason why you cannot use function pointers to call member functions is that
ordinary function pointers are usually just the memory address of the function.
To call a member function, you need to know two things:
- Which member function to call
- Which instance should be used (whose member function)
Ordinary function pointers cannot store both. C++ member function pointers are used
to store a), which is why you need to specify the instance explicitly when calling a member function pointer.
answered Sep 28 '09 at 8:55
hrnthrnt
8,49612637
8,49612637
1
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
add a comment |
1
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
1
1
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
I up voted this but would add a clarification point in case the OP doesn't know what you are referring to by "which instance". I would expand to explain the inherent 'this' pointer.
– Eric
Oct 25 '12 at 18:01
add a comment |
A function pointer to a class member is a problem that is really suited to using boost::function. Small example:
#include <boost/function.hpp>
#include <iostream>
class Dog
{
public:
Dog (int i) : tmp(i) {}
void bark ()
{
std::cout << "woof: " << tmp << std::endl;
}
private:
int tmp;
};
int main()
{
Dog* pDog1 = new Dog (1);
Dog* pDog2 = new Dog (2);
//BarkFunction pBark = &Dog::bark;
boost::function<void (Dog*)> f1 = &Dog::bark;
f1(pDog1);
f1(pDog2);
}
add a comment |
A function pointer to a class member is a problem that is really suited to using boost::function. Small example:
#include <boost/function.hpp>
#include <iostream>
class Dog
{
public:
Dog (int i) : tmp(i) {}
void bark ()
{
std::cout << "woof: " << tmp << std::endl;
}
private:
int tmp;
};
int main()
{
Dog* pDog1 = new Dog (1);
Dog* pDog2 = new Dog (2);
//BarkFunction pBark = &Dog::bark;
boost::function<void (Dog*)> f1 = &Dog::bark;
f1(pDog1);
f1(pDog2);
}
add a comment |
A function pointer to a class member is a problem that is really suited to using boost::function. Small example:
#include <boost/function.hpp>
#include <iostream>
class Dog
{
public:
Dog (int i) : tmp(i) {}
void bark ()
{
std::cout << "woof: " << tmp << std::endl;
}
private:
int tmp;
};
int main()
{
Dog* pDog1 = new Dog (1);
Dog* pDog2 = new Dog (2);
//BarkFunction pBark = &Dog::bark;
boost::function<void (Dog*)> f1 = &Dog::bark;
f1(pDog1);
f1(pDog2);
}
A function pointer to a class member is a problem that is really suited to using boost::function. Small example:
#include <boost/function.hpp>
#include <iostream>
class Dog
{
public:
Dog (int i) : tmp(i) {}
void bark ()
{
std::cout << "woof: " << tmp << std::endl;
}
private:
int tmp;
};
int main()
{
Dog* pDog1 = new Dog (1);
Dog* pDog2 = new Dog (2);
//BarkFunction pBark = &Dog::bark;
boost::function<void (Dog*)> f1 = &Dog::bark;
f1(pDog1);
f1(pDog2);
}
answered Sep 28 '09 at 13:18
BenjaminBenjamin
4031613
4031613
add a comment |
add a comment |
To create a new object you can either use placement new, as mentioned above, or have your class implement a clone() method that creates a copy of the object. You can then call this clone method using a member function pointer as explained above to create new instances of the object. The advantage of clone is that sometimes you may be working with a pointer to a base class where you don't know the type of the object. In this case a clone() method can be easier to use. Also, clone() will let you copy the state of the object if that is what you want.
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
add a comment |
To create a new object you can either use placement new, as mentioned above, or have your class implement a clone() method that creates a copy of the object. You can then call this clone method using a member function pointer as explained above to create new instances of the object. The advantage of clone is that sometimes you may be working with a pointer to a base class where you don't know the type of the object. In this case a clone() method can be easier to use. Also, clone() will let you copy the state of the object if that is what you want.
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
add a comment |
To create a new object you can either use placement new, as mentioned above, or have your class implement a clone() method that creates a copy of the object. You can then call this clone method using a member function pointer as explained above to create new instances of the object. The advantage of clone is that sometimes you may be working with a pointer to a base class where you don't know the type of the object. In this case a clone() method can be easier to use. Also, clone() will let you copy the state of the object if that is what you want.
To create a new object you can either use placement new, as mentioned above, or have your class implement a clone() method that creates a copy of the object. You can then call this clone method using a member function pointer as explained above to create new instances of the object. The advantage of clone is that sometimes you may be working with a pointer to a base class where you don't know the type of the object. In this case a clone() method can be easier to use. Also, clone() will let you copy the state of the object if that is what you want.
answered Sep 28 '09 at 9:34
Corwin JoyCorwin Joy
555412
555412
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
add a comment |
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
clones can be expensive and the OP may wish to avoid them if performance is an issue or of some concern.
– Eric
Oct 25 '12 at 17:58
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f1485983%2fcalling-c-class-methods-via-a-function-pointer%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
I still don't really understand 'why' if you want to call a objects member function then simply pass a pointer to the object? If people complain that because it enables you to encapsulate the class better why not make an interface class that all class inherit from?
– Chad
Sep 28 '09 at 8:39
It can be useful in implementing something like the command pattern although many people would use boost::function to hide the raw member pointer mechanics.
– CB Bailey
Sep 28 '09 at 8:45
Thanks for the comment. Just after so many years of programing I've seen it used all over the place. I just consider passing a object cleaner and simpler.
– Chad
Sep 28 '09 at 8:56
7
Why do you allocate that dog dynamically? You then have to manually delete the object, too. This looks a lot like you're coming from Java, C# or some other comparable language and still fight with C++. A plain automatic object (
Dog dog;
) is more likely what you want.– sbi
Sep 28 '09 at 9:18
1
@Chad: I would mostly agree but there are times where passing a reference would be more costly. Consider a loop that is iterating over some type of data (parsing, calculation, etc..) than being able to call a function based on some if/else calculations imposes a cost where just calling the pointed too function could avoid such if/then/else checks if these checks could be done before entering the loop.
– Eric
Oct 25 '12 at 18:04