Sort of a style question here. Say I have a class A which has to do a sequence of reasonably complex things to its member variable B b
class A {
public:
void DoStuffOnB(){
DoThing1();
DoThing2();
DoThing3();
}
private:
B b;
void DoThing1(){ /* modify b */ }
void DoThing2(){ /* modify b */ }
void DoThing3(){ /* modify b */ }
};
where the DoThings functions only depend on b (or other member variables and some passed parameters). If I want to make those functions re-usable in the future outside of that class, I'm better off writing them as:
class A {
public:
void DoStuffOnB(){
DoThing1(b);
DoThing2(b);
DoThing3(b);
}
private:
B b;
void DoThing1(B& b){ /* modify b */ }
void DoThing2(B& b){ /* modify b */ }
void DoThing3(B& b){ /* modify b */ }
};
and then my DoThing functions can just be copied elsewhere in the future. Am I better off writing the function to take all relevant parameters like that, or should the function only take non-member parameters?
In case the answer is "you should write the function to take all relevant parameters", why would one bother to put it in a class?
When should you use a free function, and when should you use a member function?
Assuming from the context that the "do something on B" functions only operate on the B member and not other state in A then:
If the functions directly manipulate/operate on the private state of B then they should be members of B.
Else they should be free functions.
A member function is a member function because its' scope has access to the member variables without having to use referencing and pointer syntax. As someone mentioned earlier this would most likely make it simpler to code and maintain so you would use this method unless you needed the function to be a free function that might take the same type data but from different classes in which case you would have to pass by reference or use pointers to gain access to the scope of the variable.
Should you pass member variables within member functions?
There is no need to pass member variables to member functions, since the member functions have access to all the data members.
It's similar to free standing functions accessing static file local variables. The functions have access to the statically declared variables in the same translation unit.
When should you use a freestanding function and when should you use a member function?
In general, use a member function when the functionality is associated with the object.
Use a freestanding function when
the class has static members
or functionality is associated with a class and doesn't use static
members.
You can also use freestanding functions when the same functionality can apply to different objects.
For example, let's talk serialization or outputting of an object.
One can define a method, load_from_buffer() in an object, but it won't work with POD types.
However, if a function load_from_buffer() is made freestanding, it can be overloaded for different types, such as int, char, double and with templates, an overload can be made to call objects derived from an interface.
Summary
Prefer to use member methods when they require access to data members of an object. Use static member methods when they access static data members or there is a need for the functionality without an instance of an object (think encapsulation). Freestanding functions also provide the capability of functionality to different objects based on function overloading.
There are no hard rules, just use what you think will be easiest to maintain, assist in correctness and robustness and speed up development.
Just to confuse people, here is an article by Scott Meyers:
How Non-Member functions increase encapsulation
Remember, in order for a free standing function to access data members of an object, the data members must be given public access or the function needs to be a friend of the object. The classic example is overloading the stream operators for a class.
Related
I know that when we create multiple objects of a given class type, multiple copies of the member variables are created. Each object has it's separate set of member variables. Does this work the same way with member functions too? If my class has a lot of functions, do the member functions get duplicated for each object that is created? Does each created object have it's own set of the member functions?
class demo {
public:
int height;
int width;
void setheight(int height)
{
this->height = height;
}
void getArea() const
{
return height * width;
}
// 100 more member functions.
};
This is just a hypothetical example to prove a point about the C++ compiler. Actually this is related to what I'm doing in my project. Let's suppose I have a class type with only a few member variables but lots and lots of member functions. If I create multiple objects of that class type, will I have duplication of code, with each object having it's own copy of the member function? In that case, would it be better for me to declare the functions just as regular stand alone global functions which take the object as a parameter instead, in order to avoid growing the executable?
This is just an implementation detail (the standard doesn't mandate anything particular about it), but on pretty much any implementation class methods are essentially syntactic sugar for "regular", free functions taking this as a hidden parameter1. IOW, your proposed optimization is what the compiler already does.
There's some extra machinery involved for virtual methods, as every virtual method generally "costs" one slot into the vtable of the class (and all its derived classes), but again, it's a O(1) space cost, not O(n) in the number of instances.
On some implementations there's also a difference in calling convention, e.g. on x86 VC++ methods receive this in ecx instead than on the stack as it would be if it were a free function with this as first parameter, but that's irrelevant for our discussion.
What is the advantage of having a free function (in anonymous namespace and accessible only in a single source file) and sending all variables as parameters as opposed to having a private class member function free of any parameters and accessing member variables directly?
header:
Class A {
int myVariable;
void DoSomething() {
myVariable = 1;
}
};
source:
namespace {
void DoSomething2(int &a) {
a = 1;
}
}
int A::SomeFunction() {
DoSomething2(myVariable); // calling free function
DoSomething(); // calling member function
}
If you prefer making them members, then what if I have a case where I first call a function that is not accessing any member variables, but that function calls another function which is accessing a member. Should they both be member functions or free?
see this question: Effective C++ Item 23 Prefer non-member non-friend functions to member functions
and also C++ Member Functions vs Free Functions
You should prefer free functions, in the extent that it promotes loose coupling.
Consider making it a member function only if it works on the guts of your class, and that you consider it really really tied to your class.
It is a point of the book 101 C++ coding standards, which states to prefer free function and static function over member functions.
Altough this may be considered opinion based, it allows to keep class little, and to seperate concerns.
This answer states: "the reason for this rule is that by using member functions you may rely too much on the internals of a class by accident."
One advantage of a non-member function in a source file is similar to the benefits of the Pimpl idiom: clients using your headers do not have to recompile if you change your implementation.
// widget.h
class Widget
{
public:
void meh();
private:
int bla_;
};
// widget.cpp
namespace {
void helper(Widget* w) // clients will never know about this
{ /* yadayada */ }
}
void widget::meh()
{ helper(this); }
Of course, when written like this, helper() can only use the public interface of Widget, so you gain little. You can put a friend declaration for helper() inside Widget but at some point you better switch to a full-blown Pimpl solution.
The primary advantage of free functions vs member functions is that it helps decouple the interface from the implementation. For example, std::sort doesn't need to know anything about the underlying container on which it operates, just that it's given access to a container (through iterators) that provide certain characteristics.
In your example the DoSomething2 method doesn't do much to decrease coupling since it still has to access the private member by having it passed by reference. It's almost certainly more obvious to just do the state mutation in the plain DoSomething method instead.
When you can implement a task or algorithm in terms of a class's public interface then that makes it a good candidate to make a free function. Scott Meyers summarizes a reasonable set of rules here: http://cpptips.com/nmemfunc_encap
I have a C++ singleton factory-like class called MemMgr which is in charge of managing heap memory for objects in a library:
#include <vector>
class MemMgr
{
public:
// Callback interface of functions to register with MemMgr
typedef size_t (*MemSizeFunc)(void);
void Register(MemSizeFunc memSizeFunc);
static MemMgr & GetInst(void);
// more public functionality related to managing memory
private:
// a vector (not a map) of functions pointers to keep track of
std::vector<MemSizeFunc> m_memSizeFuncs;
MemMgr(void);
MemMgr(MemMgr const &);
MemMgr & operator= (MemMgr const &);
// more private functionality related to managing memory
};
What I'd like to be able to do is to have objects of any classes that would like to utilize managed memory be able to register themselves with MemMgr via a (non-static) member function which will calculate and return the amount of managed memory that that particular object needs. Something like the following:
class MemMgrUser
{
public:
MemMgrUser(void)
{
MemMgr::GetInst().Register(GetManagedMemSize);
}
private:
size_t GetManagedMemSize(void)
{
// calculations involving member variables
}
};
(Then, prior to MemMgr actually allocating any memory, it would query the size-related functions registered to it in order to find out the amount of memory to allocate.)
However, the compiler yells at me when I try the above approach b/c I am trying to register member function pointers, not plain-vanilla function pointers.
Does anyone have any suggestions on how I could implement such functionality? I am having problems seeing how a template implementation (or polymorphic one) would be implemented.
Thank you,
Aaron
You don't even try to register a member function pointer. That would have to be specified as &MemMgrUser::GetManagedMemSize. You can't use the plain name of a member function, except in an expression that calls it.
But even if you had a member function pointer, it cannot be used in the same way as a plain function pointer of the same apparent signature. Calling a member function always requires an object to call it on. The this pointer available in the function is an additional, hidden parameter.
If you can use features of the C++11 standard library, you could typedef std::function<size_t (void)> MemSizeFunc; instead of the current typedef. That allows you to store various kinds of functions and function objects that are callable with that signature as a MemSizeFunc. In particular you could register your GetManagedMemSize member function bound to a suitable MemMgrUser object, for example as:
MemMgrUser()
{
MemMgr::GetInst().Register(std::bind(&MemMgrUser::GetManagedMemSize, *this));
}
i have made a sample example, in this i'm trying to pass a function as argument i am getting error, could you please help me
typedef void (*callbackptr)(int,int);
class Myfirst
{
public:
Myfirst();
~Myfirst();
void add(int i,callbackptr ptr)
{
ptr(i,3);
}
};
class Mysec
{
public:
Myfirst first_ptr;
Mysec();
~Mysec();
void TestCallback()
{
callbackptr pass_ptr = NULL;
pass_ptr = &Mysec::Testing;
first_ptr.add(2,&Mysec::Testing);
}
void Testing(int a,int b)
{
int c = a+b;
}
};
The type of the callback function you're passing as parameter is not defined as part of a class. You probably should define Testing as static.
You are geting an error because you are pointing to a member function. Pointers to member functions are different. See here:
http://www.parashift.com/c++-faq-lite/pointers-to-members.html#faq-33.1
A member function needs to know what instance it is working with (the this pointer) so it can't be called like any other function. If you moved the callback function out of the class (or made it static, which is similar to moving it out of the class) you could call it like any other function.
A more modern way of doing this is to use functors, e.g. boost::function and something like boost::bind :
C++ Functors - and their uses
how boost::function and boost::bind work
Those can hide the difference between member and global functions.
You are trying to access a member function pointer here, using a simple function pointer typedef, which will not work. Let me explain.
When you write a normal, non-member function (similar to C), the function's code actually exists in a location indicated by the name of the function - which you would pass to a function pointer parameter.
However, in the case of a member function, all you have is the class definition; you don't have the actual instance of the class allocated in memory yet. In such a function, since the this pointer is not yet defined, any reference to member variables wouldn't make sense, since the compiler doesn't have enough information to resolve their memory locations. In fact, member function pointers are not exact addresses; they encode more information than that (which may not be visible to you). For more, read Pointers to Member Functions.
I understand that one benefit of having static member functions is not having to initialize a class to use them. It seems to me that another advantage of them might be not having direct access to the class's not-static stuff.
For example a common practice is if you know that a function will have arguments that are not to be changed, to simply mark these constant. e.g.:
bool My_Class::do_stuff(const int not_to_be_changed_1,
std::vector<int> const * const not_to_be_changed_2)
{
//I can't change my int var, my vector pointer, or the ints inside it.
}
So is it valid to use static member functions to limit access. For example, lets say you have a function
void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
Well here we're not going to be accessing any member variables of the class. So if I changed the function to:
static void My_Class::print_error(const unsigned int error_no) {
switch (error_no) {
case 1:
std::cout << "Bad read on..." << std::endl;
break;
//...
default:
break;
}
}
I'd now get an error, if I inadvertently tried to access one of my private var, etc. (unless I pass myself an instance of my class, which would be purposeful ^_^ !)
Is this a valid technique, similar to proactively making args that should not be changed constants?
What downsides might it have in terms of efficiency or use?
My chief reason for asking is that most of the "static" tutorials I read made no mention of using it in this way, so I was wondering if there was a good reason why not to, considering it seems like a useful tool.
Edit 1: A further logical justification of this use:
I have a function print_error,as outlined above. I could use a namespace:
namespace MY_SPACE {
static void print_error(...) {
...
}
class My_Class {
....
void a(void)
}
}
But this is a pain, because I now have to lengthen ALL of my var declarations, i.e.
MY_SPACE::My_Class class_1;
all to remove a function from my class, that essentially is a member of my class.
Of course there's multiple levels of access control for functions:
//can't change pointer to list directly
void My_Class::print_error(std::vector<int> const * error_code_list) {...}
//can't change pointer to list or list members directly
void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//non-const member vars/functions
void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
//can't change pointer to list or list members directly, access
//non-static member vars/functions
static void My_Class::print_error(std::vector<int> const * const error_code_list) {...}
//can't change pointer to list or list members directly, access
//member vars/functions that are not BOTH static and const
static void My_Class::print_error(std::vector<int> const * const error_code_list) const {...}
Sure this is a bit atypical, but to lessening degrees so are using const functions and const variables. I've seen lots of examples where people could have used a const function, but didn't. Yet some people think its a good idea. I know a lot of beginning c++ programmers who wouldn't understand the implications of a const function or a static one. Likewise a lot would understand both.
So why are some people so adamantly against using this as an access control mechanism if the language/spec provides for it to be used as such, just as it does with const functions, etc.?
Any member function should have access to the other members of the object. Why are you trying to protect yourself from yourself?
Static members are generally used sparingly, factory methods for example. You'll be creating a situation that makes the next person to work with your code go "WTF???"
Don't do this. Using static as an access-control mechanism is a barbaric abomination.
One reason not to do this is because it's odd. Maintenance programmers will have a hard time understanding your code because it's so odd. Maintainable code is good code. Everybody gets const methods. Nobody gets static-as-const. The best documentation for your code is the code itself. Self-documenting code is a goal you should aspire to. Not so that you don't have to write comments, but so that they won't have to read them. Because you know they're not going to anyway.
Another reason not to do this is because you never know what the future will bring. Your print_error method above does not need to access the class' state -- now. But I can see how it one day might need to. Suppose your class is a wrapper around a UDP socket. Sometime in the middle of the session, the other end slams the door. You want to know why. The last messages you sent or received might hold a clue. Shouldn't you dump it? You need state for that.
A false reason to do this is because it provides member access control. Yes it does this, but there are already mechanisms for this. Suppose you're writing a function that you want to be sure doesn't change the state of the object. For instance, print_error shouldn't change any of the object's state. So make the method const:
class MyClass
{
public:
void print_error(const unsigned int error_no) const;
};
...
void MyClass::print_error(const unsigned int error_no) const
{
// do stuff
}
print_error is a const method, meaning effectively that the this pointer is const. You can't change any non-mutable members, and you can't call any non-const methods. Isn't this really what you want?
Static member functions should be used when they are relevant to the class but do not operate on an instance of the class.
Examples include a class of utility methods, all of which are static because you never need an actual instance of the utility class itself.
Another example is a class that uses static helper functions, and those functions are useful enough for other functions outside the class.
It is certainly fair to say that global scope functions, static member functions, and friend functions aren't quite orthogonal to one another. To a certain extent, this is largely because they are intended to have somewhat different semantic meaning to the programmer, even though they produce similar output.
In particular, the only difference between a static member method and a friend function is that the namespaces are different, the static member has a namespace of ::className::methodName and the friend function is just ::friendFunctionName. They both operate in the same way.
Well, actually there is one other difference, static methods can be accessed via pointer indirection, which can be useful in the case of polymorphic classes.
So the question is, does the function belong as "part" of the class? if so, use a static method. if not, put the method in the global scope, and make it a friend if it might need access to the private member variables (or don't if it doesn't)