Related
I'm helping a student with their homework, which is a basic threading exercise. Unfortunately, though they're required to use C++11, they're forbidden from using std::thread. I don't see the rationale, but it's not my homework.
Here's the class:
class VaccineInfo {
public:
VaccineInfo(const std::string &t_input_filename):
input_filename(t_input_filename)
{ }
VaccineInfo() = delete;
static void *count_vaccines(void *t_vi);
int v1_count() { return vaccine_count["v1"]; }
int v2_count() { return vaccine_count["v2"]; }
int v3_count() { return vaccine_count["v3"]; }
private:
std::string input_filename;
std::map<std::string, int> vaccine_count {
{ "v1", 0 },
{ "v2", 0 },
{ "v3", 0 }
};
};
void *VaccineInfo::count_vaccines(void *t_vi) {
VaccineInfo *vi = reinterpret_cast<VaccineInfo*>(t_vi);
std::ifstream input_file;
std::string input_line;
input_file.open(vi->input_filename);
if (!input_file.good()) {
std::cerr << "No such file " << vi->input_filename << std::endl;
return nullptr;
}
while (std::getline(input_file, input_line)) {
vi->vaccine_count[input_line]++;
}
return nullptr;
}
And here's where pthreads comes in.
std::vector<std::string> filenames = find_filenames(".");
std::vector<pthread_t> thread_handles;
std::vector<VaccineInfo> vi_vector;
vi_vector.reserve(filenames.size());
for(const std::string &filename : filenames) {
pthread_t tid;
thread_handles.push_back(tid);
vi_vector.emplace_back(VaccineInfo(filename));
pthread_create(
&thread_handles.back(), nullptr, &VaccineInfo::count_vaccines,
static_cast<void*>(&vi_vector.back()));
}
for (const pthread_t tid : thread_handles) {
pthread_join(tid, nullptr);
}
It's a pretty basic exercise, except for how much fluff you have to do to get the old and the new to play nice. And that's what's got me wondering - does using a static member method as the start_routine argument to pthread_create have any undesirable side effects? I know static member variables and functions don't "belong" to any objects, but I normally think of static variables as being one-per-class, regardless of the number of objects. If there's only one copy of the static member function, as well, that seems like you'd be shooting yourself in the foot for parallelization.
Would it just be better, in this case, to make vaccine_count public and make count_vaccines() a global function?
Do hit me with whatever detail you can muster; I'm very curious. =) And, as always, thank you all for your time and effort.
except for how much fluff you have to do to get the old and the new to play nice.
Well, in the STL, that's essentially what the std::thread is actually doing. If you create a thread and force it to cause a stack unwinding, and if you look at said stack, you'll see a lot of weird pointer arithmetic happening with this and pthread_create (or CreateThread on Windows).
That being said, it's not unusual in any way to use a static function of a class that then calls a private member of that class on an object instance, even with the std::thread, it really just depends on what you need those functions to do.
does using a static member method as the start_routine argument to pthread_create have any undesirable side effects?
No. At least not from the perspective of functionality; that is, creating a thread on a static member won't cause any UB or crashes directly just because you are using a static function.
You do have to account for the fact that your operating on a static member function, but that's no different from having to account for constructors/destructors or any function of the language itself. Since this is a homework assignment, it's likely the professor is trying to teach "how things work" less than "how to use C++11".
Would it just be better, in this case, to make vaccine_count public and make count_vaccines() a global function?
Yes and no. Having vaccine_count as a private member then means that count_vaccines must be a friend or static function, and given that vaccine_count seems like an "important" data point that you wouldn't want a "user of the code" inadvertently setting, it's probably better to keep it private.
You could add getters and setters, but that might complicate the code unnecessarily.
You could also just make it a public variable if you trust the users of the code to protect that variable (unlikely), and you could also just make count_vaccines a free/global function, but then you need to have the function after the class declaration. And if the class is a complex class (maybe has templates or some other C++ notion), then it can really complicate the code in how you operate on the class.
So yes, it could go that way, but the professor is likely trying to teach the idea of what a static function is, how threads operate on the class and how pointers work within the constructs of this exercise, among other things.
If you have a static member variable, all objects access that variable.
That's not what static means in this context. The static keyword in C++ simply means that you do not need an object reference to call that code. So a static member variable can be accessed, not just by any object, but by any code, take this example:
class Data {
public:
static int x_val;
int y_val;
};
int Data::x_val; // have to declare it since it's static
int main(int argc, char* argv[]) {
Data::x_val = 10; // works because it's static.
Data::y_val = 10; // error: accessing a non-static member
Data obj;
obj.y_val = 10; // ok because it's a member variable
obj.x_val = 20; // this works as the complier ultimately translates this to `Data::x_val = 20`
// BUT, referencing a static member/function on an object instance is "bad form"
return 0;
}
If you have a static member function... can it be called on more than one core simultaneously?
The static keyword has no effect on which core, or thread, said function is called on or if can be done in parallel.
A CPU core can only execute 1 machine level instruction per clock cycle (so essentially, just 1 assembly instruction), when a C++ program is compiled, linked and assembled, it is these "assembled" set of instructions base on the syntax you wrote that are executed on the core (or cores) of your CPU, not the static functions.
That static function is just an address in memory that gets called on any number of threads on any CPU core that the OS determines at any given time in your program.
Yes, you could call an OS API that pins that thread of execution calling that function to a specific core, but that's a different subject.
And for a last little bit of fun for you, on an assembly level, C++ functions basically get compiled into C-like functions (an extreme over simplification, but merely for demonstration):
C++
class Data {
public:
void increment() {
this->y_val += 1024;
}
private:
int y_val;
};
int main() {
Data obj;
obj.y_val = 42;
obj.increment(); // obj.y_val == 1066
return 0;
}
C
struct Data {
int y_val;
};
void Data_increment(Data* this) {
this->y_val += 1024;
}
int main() {
Data obj;
obj.y_val = 42;
increment(&obj); // obj.y_val == 1066
return 0;
}
Again, an over simplification, but the point is to illustrate how it all builds to assembly and what the assembly does.
As far as I know each created object has its own address, and each object's method also has its own address. I want to verify that with the following idea:
Step 1: Build class A with public method, its name is "method".
Step 2: Create two objects in class A, they are object "b" and object "c".
Step 3: Access the addresses of "b.method" and "c.method" to check that they are equal by using a function pointer.
But I met the problem in step 3 and have found every way to solve but failed.
So I posted up here to ask people to help me how to verify what I said above. Thanks everyone!
And here is my C++ code:
#include<iostream>
using namespace std;
class A
{
public:
int a;
void method()
{
//do something
}
static void (*fptr)();
};
int main()
{
A b, c;
A::fptr= &(b.method); //error: cannot convert 'A::method' from type
// 'void(A::)()' to type 'void (*)()'
cout << A::fptr << endl;
A::fptr= &(c.method); //error: cannot convert 'A::method' from type
//'void(A::)()' to type 'void (*)()'
cout << A::fptr << endl;
return 0;
}
Member functions are not like typical functions. The main difference is the way they are called (they have an implicit this argument), but that difference is enough for the language to demand a new way of defining pointers to them. See here for more details.
The following code prints the address in memory of a method:
#include <iostream>
class A {
public:
void method() {
}
};
int main() {
auto ptr = &A::method;
std::cout << reinterpret_cast<void*>(ptr) << "\n";
return 0;
}
As you can see, I had to cast the pointer to a void* to fool the compiler. G++ prints out a warning on that line, but otherwise does what you want with it.
Notice that the type of ptr is void (A::*)(), i.e. "a pointer to a method in A that receives no arguments and returns void". A pointer to methods in your B and C may be slightly different. They should convert to pointers to A, so you might want to go through that when comparing (or just cast to void* and ignore the warning).
Edited to add:
It seems no cast is needed for comparison. You can just directly compare the two pointers to methods, and they will return true or false correctly.
Thank you everyone!
I've been wondering about this for a long time, and now I've figured out the answer myself, there's only one "method()" that's created on memory, even if there are hundreds of objects created. All objects created that want to use this method will have to find the address of this method. Here is the code to prove what I said:
#include<iostream>
using namespace std;
class A
{
public:
int a;
void method()
{
//do something
}
static void (*fptr)();
};
int main()
{
A b,c;
if(&(b.method)==&(c.method))
{
cout<<"they are same\n";
}
else
{
cout<<"they are not same\n";
}
return 0;
}
The compiler and linker does not have to give distinct functions, distinct implementations.
On at least some platforms, the compiler will spot that 2 functions have the same implementation, and merge the 2 functions into a single piece of code. That limits the amount of bloat added by the template system, but stops it being a guaranteed behavior to identify different member functions.
The compiler can
inline all the examples of a single piece of code, and the result is it doesn't have an address.
share implementations where the code is the same.
create multiple implementations of the same function if it thinks it can be done faster.
When C++ was invented, there was a lot of effort to ensure that a C++ compilation unit was able to call a C compilation unit, and the result of this effort, was that many items of the C++ implementation became visible using compatibility tricks.
The C++ pointer to member function had no backwards-compatibility baggage, and thus no reason to allow it to be inspected. As such it is an opaque item, which can be implemented in multiple ways.
In your example there is only one copy of the method in memory. But i cannot think of any easy way to verify that. You can make thousands of objects and see the memory consumption. You can explore the memory occupied by your object in debugger. The memory consumption may be affected by operating system strategy for assigning memory to process. You can also explore disassembly at https://gcc.godbolt.org/
Relevant start for you would be https://godbolt.org/g/emRYQy
I'm working on a code which needs to be extremely flexible in nature, i.e. especially very easy to extend later also by other people. But I'm facing a problem now about which I do not even know in principal how to properly deal with:
I'm having a rather complex Algorithm, which at some point is supposed to converge. But due to its complexity there are several different criteria to check for convergence, and depending on the circumstances (or input) I would want to have different convergence criteria activated. Also it should easily be possible to create new convergence criteria without having to touch the algorithm itself. So ideally I would like to have an abstract ConvergenceChecker class from which I can inherit and let the algorithm have a vector of those, e.g. like this:
//Algorithm.h (with include guards of course)
class Algorithm {
//...
vector<ConvergenceChecker*> _convChecker;
}
//Algorithm.cpp
void runAlgorithm() {
bool converged=false;
while(true){
//Algorithm performs a cycle
for (unsigned i=0; i<_convChecker.size(); i++) {
// Check for convergence with each criterion
converged=_convChecker[i]->isConverged();
// If this criterion is not satisfied, forget about the following ones
if (!converged) { break; }
}
// If all are converged, break out of the while loop
if (converged) { break; }
}
}
The problem with this is that each ConvergenceChecker needs to know something about the currently running Algorithm, but each one might need to know totally different things from the algorithm. Say the Algorithm changes _foo _bar and _fooBar during each cycle, but one possible ConvergenceChecker only needs to know _foo, another one _foo and _bar, and it might be that some day a ConvergenceChecker needing _fooBar will be implemented. Here are some ways I already tried to solve this:
Give the function isConverged() a large argument list (containing _foo, _bar, and _fooBar). Disadvantages: Most of the variables used as arguments will not be used in most cases, and if the Algorithm would be extended by another variable (or a similar algorithm inherits from it and adds some variables) quite some code would have to be modified. -> possible, but ugly
Give the function isConverged() the Algorithm itself (or a pointer to it) as an argument. Problem: Circular dependency.
Declare isConverged() as a friend function. Problem (among others): Cannot be defined as a member function of different ConvergenceCheckers.
Use an array of function pointers. Does not solve the problem at all, and also: where to define them?
(Just came up with this while writing this question) Use a different class which holds the data, say AlgorithmData having Algorithm as a friend class, then provide the AlgorithmData as a function argument. So, like 2. but maybe getting around circular dependency problems. (Did not test this yet.)
I'd be happy to hear your solutions about this (and problems you see with 5.).
Further notes:
Question title: I'm aware that 'strongly dependent classes' already says that most probably one is doing something very wrong with designing the code, still I guess a lot of people might end up with having that problem and would like to hear possibilities to avoid it, so I'd rather keep that ugly expression.
Too easy?: Actually the problem I presented here was not complete. There will be a lot of different Algorithms in the code inheriting from each other, and the ConvergenceCheckers should of course ideally work in appropriate cases without any further modification even if new Algorithms come up. Feel free to comment on this as well.
Question style: I hope the question is neither too abstract nor too special, and I hope it did not get too long and is understandable. So please also don't hesitate to comment on the way I ask this question so that I can improve on that.
Actually, your solution 5 sounds good.
When in danger of introducing circular dependencies, the best remedy usually is to extract the part that both need, and moving it to a separate entity; exactly as extracting the data used by the algorithm into a separate class/struct would do in your case!
Another solution would be passing your checker an object that provides the current algorithm state in response to parameter names expressed as string names. This makes it possible to separately compile your conversion strategies, because the interface of this "callback" interface stays the same even if you add more parameters to your algorithm:
struct AbstractAlgorithmState {
virtual double getDoubleByName(const string& name) = 0;
virtual int getIntByName(const string& name) = 0;
};
struct ConvergenceChecker {
virtual bool converged(const AbstractAlgorithmState& state) = 0;
};
That is all the implementers of the convergence checker need to see: they implement the checker, and get the state.
You can now build a class that is tightly coupled with your algorithm implementation to implement AbstractAlgorithmState and get the parameter based on its name. This tightly coupled class is private to your implementation, though: the callers see only its interface, which never changes:
class PrivateAlgorithmState : public AbstractAlgorithmState {
private:
const Algorithm &algorithm;
public:
PrivateAlgorithmState(const Algorithm &alg) : algorithm(alg) {}
...
// Implement getters here
}
void runAlgorithm() {
PrivateAlgorithmState state(*this);
...
converged=_convChecker[i]->converged(state);
}
Using a separate data/state structure seems easy enough - just pass it to the checker as a const reference for read-only access.
class Algorithm {
public:
struct State {
double foo_;
double bar_;
double foobar_;
};
struct ConvergenceChecker {
virtual ~ConvergenceChecker();
virtual bool isConverged(State const &) = 0;
}
void addChecker(std::unique_ptr<ConvergenceChecker>);
private:
std::vector<std::unique_ptr<ConvergenceChecker>> checkers_;
State state_;
bool isConverged() {
const State& csr = state_;
return std::all_of(checkers_.begin(),
checkers_.end(),
[csr](std::unique_ptr<ConvergenceChecker> &cc) {
return cc->isConverged(csr);
});
}
};
Maybe the decorator pattern can help in simplifying an (unknown) set of convergence checks. This way you can keep the algorithm itself agnostic to what convergence checks may occur and you don't require a container for all the checks.
You would get something along these lines:
class ConvergenceCheck {
private:
ConvergenceCheck *check;
protected:
ConvergenceCheck(ConvergenceCheck *check):check(check){}
public:
bool converged() const{
if(check && check->converged()) return true;
return thisCheck();
}
virtual bool thisCheck() const=0;
virtual ~ConvergenceCheck(){ delete check; }
};
struct Check1 : ConvergenceCheck {
public:
Check1(ConvergenceCheck* check):ConvergenceCheck(check) {}
bool thisCheck() const{ /* whatever logic you like */ }
};
You can then make arbitrary complex combinations of convergence checks while only keeping one ConvergenceCheck* member in Algorithm. For example, if you want to check two criteria (implemented in Check1 and Check2):
ConvergenceCheck *complex=new Check2(new Check1(nullptr));
The code is not complete, but you get the idea. Additionally, if you are a performance fanatic and are afraid of the virtual function call (thisCheck), you can apply the curiously returning template pattern to eliminate that.
Here is a complete example of decorators to check constraints on an int, to give an idea of how it works:
#include <iostream>
class Check {
private:
Check *check_;
protected:
Check(Check *check):check_(check){}
public:
bool check(int test) const{
if(check_ && !check_->check(test)) return false;
return thisCheck(test);
}
virtual bool thisCheck(int test) const=0;
virtual ~Check(){ delete check_; }
};
class LessThan5 : public Check {
public:
LessThan5():Check(NULL){};
LessThan5(Check* check):Check(check) {};
bool thisCheck(int test) const{ return test < 5; }
};
class MoreThan3 : public Check{
public:
MoreThan3():Check(NULL){}
MoreThan3(Check* check):Check(check) {}
bool thisCheck(int test) const{ return test > 3; }
};
int main(){
Check *morethan3 = new MoreThan3();
Check *lessthan5 = new LessThan5();
Check *both = new LessThan5(new MoreThan3());
std::cout << morethan3->check(3) << " " << morethan3->check(4) << " " << morethan3->check(5) << std::endl;
std::cout << lessthan5->check(3) << " " << lessthan5->check(4) << " " << lessthan5->check(5) << std::endl;
std::cout << both->check(3) << " " << both->check(4) << " " << both->check(5);
}
Output:
0 1 1
1 1 0
0 1 0
I've read through this article, and what I take from it is that when you want to call a pointer to a member function, you need an instance (either a pointer to one or a stack-reference) and call it so:
(instance.*mem_func_ptr)(..)
or
(instance->*mem_func_ptr)(..)
My question is based on this: since you have the instance, why not call the member function directly, like so:
instance.mem_func(..) //or: instance->mem_func(..)
What is the rational/practical use of pointers to member functions?
[edit]
I'm playing with X-development & reached the stage where I am implementing widgets; the event-loop-thread for translating the X-events to my classes & widgets needs to start threads for each widget/window when an event for them arrives; to do this properly I thought I needed function-pointers to the event-handlers in my classes.
Not so: what I did discover was that I could do the same thing in a much clearer & neater way by simply using a virtual base class. No need whatsoever for pointers to member-functions. It was while developing the above that the doubt about the practical usability/meaning of pointers to member-functions arose.
The simple fact that you need a reference to an instance in order to use the member-function-pointer, obsoletes the need for one.
[edit - #sbi & others]
Here is a sample program to illustrate my point:
(Note specifically 'Handle_THREE()')
#include <iostream>
#include <string>
#include <map>
//-----------------------------------------------------------------------------
class Base
{
public:
~Base() {}
virtual void Handler(std::string sItem) = 0;
};
//-----------------------------------------------------------------------------
typedef void (Base::*memfunc)(std::string);
//-----------------------------------------------------------------------------
class Paper : public Base
{
public:
Paper() {}
~Paper() {}
virtual void Handler(std::string sItem) { std::cout << "Handling paper\n"; }
};
//-----------------------------------------------------------------------------
class Wood : public Base
{
public:
Wood() {}
~Wood() {}
virtual void Handler(std::string sItem) { std::cout << "Handling wood\n"; }
};
//-----------------------------------------------------------------------------
class Glass : public Base
{
public:
Glass() {}
~Glass() {}
virtual void Handler(std::string sItem) { std::cout << "Handling glass\n"; }
};
//-----------------------------------------------------------------------------
std::map< std::string, memfunc > handlers;
void AddHandler(std::string sItem, memfunc f) { handlers[sItem] = f; }
//-----------------------------------------------------------------------------
std::map< Base*, memfunc > available_ONE;
void AddAvailable_ONE(Base *p, memfunc f) { available_ONE[p] = f; }
//-----------------------------------------------------------------------------
std::map< std::string, Base* > available_TWO;
void AddAvailable_TWO(std::string sItem, Base *p) { available_TWO[sItem] = p; }
//-----------------------------------------------------------------------------
void Handle_ONE(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
std::map< Base*, memfunc >::iterator it;
Base *inst = NULL;
for (it=available_ONE.begin(); ((it != available_ONE.end()) && (inst==NULL)); it++)
{
if (it->second == f) inst = it->first;
}
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_TWO(std::string sItem)
{
memfunc f = handlers[sItem];
if (f)
{
Base *inst = available_TWO[sItem];
if (inst) (inst->*f)(sItem);
else std::cout << "No instance of handler for: " << sItem << "\n";
}
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
void Handle_THREE(std::string sItem)
{
Base *inst = available_TWO[sItem];
if (inst) inst->Handler(sItem);
else std::cout << "No handler for: " << sItem << "\n";
}
//-----------------------------------------------------------------------------
int main()
{
Paper p;
Wood w;
Glass g;
AddHandler("Paper", (memfunc)(&Paper::Handler));
AddHandler("Wood", (memfunc)(&Wood::Handler));
AddHandler("Glass", (memfunc)(&Glass::Handler));
AddAvailable_ONE(&p, (memfunc)(&Paper::Handler));
AddAvailable_ONE(&g, (memfunc)(&Glass::Handler));
AddAvailable_TWO("Paper", &p);
AddAvailable_TWO("Glass", &g);
std::cout << "\nONE: (bug due to member-function address being relative to instance address)\n";
Handle_ONE("Paper");
Handle_ONE("Wood");
Handle_ONE("Glass");
Handle_ONE("Iron");
std::cout << "\nTWO:\n";
Handle_TWO("Paper");
Handle_TWO("Wood");
Handle_TWO("Glass");
Handle_TWO("Iron");
std::cout << "\nTHREE:\n";
Handle_THREE("Paper");
Handle_THREE("Wood");
Handle_THREE("Glass");
Handle_THREE("Iron");
}
{edit] Potential problem with direct-call in above example:
In Handler_THREE() the name of the method must be hard-coded, forcing changes to be made anywhere that it is used, to apply any change to the method. Using a pointer to member-function the only additional change to be made is where the pointer is created.
[edit] Practical uses gleaned from the answers:
From answer by Chubsdad:
What: A dedicated 'Caller'-function is used to invoke the mem-func-ptr;Benefit: To protect code using function(s) provided by other objectsHow: If the particular function(s) are used in many places and the name and/or parameters change, then you only need to change the name where it is allocated as pointer, and adapt the call in the 'Caller'-function. (If the function is used as instance.function() then it must be changed everywhere.)
From answer by Matthew Flaschen:
What: Local specialization in a classBenefit: Makes the code much clearer,simpler and easier to use and maintainHow: Replaces code that would conventionally be implement using complex logic with (potentially) large switch()/if-then statements with direct pointers to the specialization; fairly similar to the 'Caller'-function above.
The same reason you use any function pointer: You can use arbitrary program logic to set the function pointer variable before calling it. You could use a switch, an if/else, pass it into a function, whatever.
EDIT:
The example in the question does show that you can sometimes use virtual functions as an alternative to pointers to member functions. This shouldn't be surprising, because there are usually multiple approaches in programming.
Here's an example of a case where virtual functions probably don't make sense. Like the code in the OP, this is meant to illustrate, not to be particularly realistic. It shows a class with public test functions. These use internal, private, functions. The internal functions can only be called after a setup, and a teardown must be called afterwards.
#include <iostream>
class MemberDemo;
typedef void (MemberDemo::*MemberDemoPtr)();
class MemberDemo
{
public:
void test1();
void test2();
private:
void test1_internal();
void test2_internal();
void do_with_setup_teardown(MemberDemoPtr p);
};
void MemberDemo::test1()
{
do_with_setup_teardown(&MemberDemo::test1_internal);
}
void MemberDemo::test2()
{
do_with_setup_teardown(&MemberDemo::test2_internal);
}
void MemberDemo::test1_internal()
{
std::cout << "Test1" << std::endl;
}
void MemberDemo::test2_internal()
{
std::cout << "Test2" << std::endl;
}
void MemberDemo::do_with_setup_teardown(MemberDemoPtr mem_ptr)
{
std::cout << "Setup" << std::endl;
(this->*mem_ptr)();
std::cout << "Teardown" << std::endl;
}
int main()
{
MemberDemo m;
m.test1();
m.test2();
}
My question is based on this: since you have the instance, why not call the member function directly[?]
Upfront: In more than 15 years of C++ programming, I have used members pointers maybe twice or thrice. With virtual functions being around, there's not all that much use for it.
You would use them if you want to call a certain member functions on an object (or many objects) and you have to decide which member function to call before you can find out for which object(s) to call it on. Here is an example of someone wanting to do this.
I find the real usefulness of pointers to member functions comes when you look at a higher level construct such as boost::bind(). This will let you wrap a function call as an object that can be bound to a specific object instance later on and then passed around as a copyable object. This is a really powerful idiom that allows for deferred callbacks, delegates and sophisticated predicate operations. See my previous post for some examples:
https://stackoverflow.com/questions/1596139/hidden-features-and-dark-corners-of-stl/1596626#1596626
Member functions, like many function pointers, act as callbacks. You could manage without them by creating some abstract class that calls your method, but this can be a lot of extra work.
One common use is algorithms. In std::for_each, we may want to call a member function of the class of each member of our collection. We also may want to call the member function of our own class on each member of the collection - the latter requires boost::bind to achieve, the former can be done with the STL mem_fun family of classes (if we don't have a collection of shared_ptr, in which case we need to boost::bind in this case too). We could also use a member function as a predicate in certain lookup or sort algorithms. (This removes our need to write a custom class that overloads operator() to call a member of our class, we just pass it in directly to boost::bind).
The other use, as I mentioned, are callbacks, often in event-driven code. When an operation has completed we want a method of our class called to handle the completion. This can often be wrapped into a boost::bind functor. In this case we have to be very careful to manage the lifetime of these objects correctly and their thread-safety (especially as it can be very hard to debug if something goes wrong). Still, it once again can save us from writing large amounts of "wrapper" code.
There are many practical uses. One that comes to my mind is as follows:
Assume a core function such as below (suitably defined myfoo and MFN)
void dosomething(myfoo &m, MFN f){ // m could also be passed by reference to
// const
m.*f();
}
Such a function in the presence of pointer to member functions, becomes open for extension and closed for modification (OCP)
Also refer to Safe bool idiom which smartly uses pointer to members.
The best use of pointers to member functions is to break dependencies.
Good example where pointer to member function is needed is Subscriber/Publisher pattern :
http://en.wikipedia.org/wiki/Publish/subscribe
In my opinion, member function pointers do are not terribly useful to the average programmer in their raw form. OTOH, constructs like ::std::tr1::function that wrap member function pointers together with a pointer to the object they're supposed to operate on are extremely useful.
Of course ::std::tr1::function is very complex. So I will give you a simple example that you wouldn't actually use in practice if you had ::std::tr1::function available:
// Button.hpp
#include <memory>
class Button {
public:
Button(/* stuff */) : hdlr_(0), myhandler_(false) { }
~Button() {
// stuff
if (myhandler_) {
delete hdlr_;
}
}
class PressedHandler {
public:
virtual ~PressedHandler() = 0;
virtual void buttonPushed(Button *button) = 0;
};
// ... lots of stuff
// This stores a pointer to the handler, but will not manage the
// storage. You are responsible for making sure the handler stays
// around as long as the Button object.
void setHandler(const PressedHandler &hdlr) {
hdlr_ = &hdlr;
myhandler_ = false;
}
// This stores a pointer to an object that Button does not manage. You
// are responsible for making sure this object stays around until Button
// goes away.
template <class T>
inline void setHandlerFunc(T &dest, void (T::*pushed)(Button *));
private:
const PressedHandler *hdlr_;
bool myhandler_;
template <class T>
class PressedHandlerT : public Button::PressedHandler {
public:
typedef void (T::*hdlrfuncptr_t)(Button *);
PressedHandlerT(T *ob, hdlrfuncptr_t hdlr) : ob_(ob), func_(hdlr) { }
virtual ~PressedHandlerT() {}
virtual void buttonPushed(Button *button) { (ob_->*func_)(button); }
private:
T * const ob_;
const hdlrfuncptr_t func_;
};
};
template <class T>
inline void Button::setHandlerFunc(T &dest, void (T::*pushed)(Button *))
{
PressedHandler *newhandler = new PressedHandlerT<T>(&dest, pushed);
if (myhandler_) {
delete hdlr_;
}
hdlr_ = newhandler;
myhandler_ = true;
}
// UseButton.cpp
#include "Button.hpp"
#include <memory>
class NoiseMaker {
public:
NoiseMaker();
void squee(Button *b);
void hiss(Button *b);
void boo(Button *b);
private:
typedef ::std::auto_ptr<Button> buttonptr_t;
const buttonptr_t squeebutton_, hissbutton_, boobutton_;
};
NoiseMaker::NoiseMaker()
: squeebutton_(new Button), hissbutton_(new Button), boobutton_(new Button)
{
squeebutton_->setHandlerFunc(*this, &NoiseMaker::squee);
hissbutton_->setHandlerFunc(*this, &NoiseMaker::hiss);
boobutton_->setHandlerFunc(*this, &NoiseMaker::boo);
}
Assuming Button is in a library and not alterable by you, I would enjoy seeing you implement that cleanly using a virtual base class without resorting to a switch or if else if construct somewhere.
The whole point of pointers of pointer-to-member function type is that they act as a run-time way to reference a specific method. When you use the "usual" syntax for method access
object.method();
pointer->method();
the method part is a fixed, compile-time specification of the method you want to call. It is hardcoded into your program. It can never change. But by using a pointer of pointer-to-member function type you can replace that fixed part with a variable, changeable at run-time specification of the method.
To better illustrate this, let me make the following simple analogy. Let's say you have an array
int a[100];
You can access its elements with fixed compile-time index
a[5]; a[8]; a[23];
In this case the specific indices are hardcoded into your program. But you can also access array's elements with a run-time index - an integer variable i
a[i];
the value of i is not fixed, it can change at run-time, thus allowing you to select different elements of the array at run-time. That is very similar to what pointers of pointer-to-member function type let you do.
The question you are asking ("since you have the instance, why not call the member function directly") can be translated into this array context. You are basically asking: "Why do we need a variable index access a[i], when we have direct compile-time constant access like a[1] and a[3]?" I hope you know the answer to this question and realize the value of run-time selection of specific array element.
The same applies to pointers of pointer-to-member function type: they, again, let you to perform run-time selection of a specific class method.
The use case is that you have several member methods with the same signature, and you want to build logic which one should be called under given circumstances. This can be helpful to implement state machine algorithms.
Not something you use everyday...
Imagine for a second you have a function that could call one of several different functions depending on parameters passed.
You could use a giant if/else if statement
You could use a switch statement
Or you could use a table of function pointers (a jump table)
If you have a lot of different options the jump table can be a much cleaner way of arranging your code ...
Its down to personal preference though. Switch statement and jump table correspond to more or less the same compiled code anyway :)
Member pointers + templates = pure win.
e.g. How to tell if class contains a certain member function in compile time
or
template<typename TContainer,
typename TProperty,
typename TElement = decltype(*Container().begin())>
TProperty grand_total(TContainer& items, TProperty (TElement::*property)() const)
{
TProperty accum = 0;
for( auto it = items.begin(), end = items.end(); it != end; ++it) {
accum += (it->*property)();
}
return accum;
}
auto ship_count = grand_total(invoice->lineItems, &LineItem::get_quantity);
auto sub_total = grand_total(invoice->lineItems, &LineItem::get_extended_total);
auto sales_tax = grand_total(invoice->lineItems, &LineItem::calculate_tax);
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
This is completely missing the point. There are two indepedent concerns here:
what action to take at some later point in time
what object to perform that action on
Having a reference to an instance satisfies the second requirement. Pointers to member functions address the first: they are a very direct way to record - at one point in a program's execution - which action should be taken at some later stage of execution, possibly by another part of the program.
EXAMPLE
Say you have a monkey that can kiss people or tickle them. At 6pm, your program should set the monkey loose, and knows whom the monkey should visit, but around 3pm your user will type in which action should be taken.
A beginner's approach
So, at 3pm you could set a variable "enum Action { Kiss, Tickle } action;", then at 6pm you could do something like "if (action == Kiss) monkey->kiss(person); else monkey->tickle(person)".
Issues
But that introducing an extra level of encoding (the Action type's introduced to support this - built in types could be used but would be more error prone and less inherently meaningful). Then - after having worked out what action should be taken at 3pm, at 6pm you have to redundantly consult that encoded value to decide which action to take, which will require another if/else or switch upon the encoded value. It's all clumsy, verbose, slow and error prone.
Member function pointers
A better way is to use a more specialised varibale - a member function pointer - that directly records which action to perform at 6pm. That's what a member function pointer is. It's a kiss-or-tickle selector that's set earlier, creating a "state" for the monkey - is it a tickler or a kisser - which can be used later. The later code just invokes whatever function's been set without having to think about the possibilities or have any if/else-if or switch statements.
To invoke it, you need a reference to an instance, but then you can call the func direct & don't need a pointer to it.
Back to this. So, this is good if you make the decision about which action to take at compile time (i.e. a point X in your program, it'll definitely be a tickle). Function pointers are for when you're not sure, and want to decouple the setting of actions from the invocation of those actions.
For debugging, I would like to add some counter variables to my class. But it would be nice to do it without changing the header to cause much recompiling.
If Ive understood the keyword correctly, the following two snippets would be quite identical. Assuming of course that there is only one instance.
class FooA
{
public:
FooA() : count(0) {}
~FooA() {}
void update()
{
++count;
}
private:
int count;
};
vs.
class FooB
{
public:
FooB() {}
~FooB() {}
void update()
{
static int count = 0;
++count;
}
};
In FooA, count can be accessed anywhere within the class, and also bloats the header, as the variable should be removed when not needed anymore.
In FooB, the variable is only visible within the one function where it exists. Easy to remove later. The only drawback I can think of is the fact that FooB's count is shared among all instances of the class, but thats not a problem in my case.
Is this correct use of the keyword? I assume that once count is created in FooB, it stays created and is not re-initialized to zero every call to update.
Are there any other caveats or headsup I should be aware of?
Edit: After being notified that this would cause problems in multithreaded environments, I clarify that my codebase is singlethreaded.
Your assumptions about static function variables are correct. If you access this from multiple threads, it may not be correct. Consider using InterlockedIncrement().
What you really want, for your long term C++ toolbox is a threadsafe, general purpose debug counters class that allows you to drop it in anywhere and use it, and be accessible from anywhere else to print it. If your code is performance sensitive, you probably want it to automatically do nothing in non-debug builds.
The interface for such a class would probably look like:
class Counters {
public:
// Counters singleton request pattern.
// Counters::get()["my-counter"]++;
static Counters& get() {
if (!_counters) _counters = new Counters();
}
// Bad idea if you want to deal with multithreaded things.
// If you do, either provide an Increment(int inc_by); function instead of this,
// or return some sort of atomic counter instead of an int.
int& operator[](const string& key) {
if (__DEBUG__) {
return _counter_map.operator[](key);
} else {
return _bogus;
}
}
// you have to deal with exposing iteration support.
private:
Counters() {}
// Kill copy and operator=
void Counters(const Counters&);
Counters& operator=(const Counters&);
// Singleton member.
static Counters* _counters;
// Map to store the counters.
std::map<string, int> _counter_map;
// Bogus counter for opt builds.
int _bogus;
};
Once you have this, you can drop it in at will wherever you want in your .cpp file by calling:
void Foo::update() {
// Leave this in permanently, it will automatically get killed in OPT.
Counters::get()["update-counter"]++;
}
And in your main, if you have built in iteration support, you do:
int main(...) {
...
for (Counters::const_iterator i = Counters::get().begin(); i != Countes::get().end(); ++i) {
cout << i.first << ": " << i.second;
}
...
}
Creating the counters class is somewhat heavy weight, but if you are doing a bunch of cpp coding, you may find it useful to write once and then be able to just link it in as part of any lib.
The major problems with static variables occur when they are used together with multi-threading. If your app is single-threaded, what you are doing is quite correct.
What I usually do in this situation is to put count in a anonymous namespace in the source file for the class. This means that you can add/remove the variable at will, it can can used anywhere in the file, and there is no chance of a name conflict. It does have the drawback that it can only be used in functions in the source file, not inlined functions in the header file, but I think that is what you want.
In file FooC.cpp
namespace {
int count=0;
}
void FooC::update()
{
++count;
}