Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When should functions be member functions?

Tags:

c++

I have a colleague in my company whose opinions I have a great deal of respect for, but I simply cannot understand one of his preferred styles of writing code in C++.

For example, given there is some class A, he'll write global functions of the type:

void foo( A *ptrToA ){} 

or:

void bar( const A &refToA ){} 

My first instinct upon seeing global functions like that is: "Why aren't these members of A?" He'll insist up and down that this is consistent with recommendations for good practice in C++, because foo and bar can perform all they need to perform by using the public interface of A. For example, he'll argue that this is completely consistent with Scott Meyers Effective C++ recommendations. I find it hard to reconcile this with item 19 in that book which basically says everything should be a member function with a few exceptions (operator<< and operator>> and functions that need dynamic type conversion). Furthermore, while I agree that the functions can do what they need to do with the public interface of A, in my opinion, that's largely the result of people writing classes that have getters and setters for every data member of class A. So with that public interface, A is an over-glorified struct and you certainly can do anything with the public interface. Personally, I don't think that should be exploited, I think it should be discouraged.

Obviously, this is only possible in a language like C++ that is not pure object oriented, so I guess one way of looking at it is that my colleague does not favor a pure object oriented approach to software design. Does anyone know of any literature that supports this position as a best practice? Or does anyone agree with this and can possibly explain it to me in a different way than my colleague has so that I might see the light? Or does everyone agree with my current feeling that this just doesn't make much sense?

Edit: Let me give a better code example.

class Car {     Wheel frontLeft;     Wheel frontRight;     Wheel rearLeft;     Wheel rearRight;     Wheel spareInTrunk;  public:     void wheelsOnCar( list< Wheel > &wheels )     {         wheels.push_back( frontLeft );         wheels.push_back( frontRight);         wheels.push_back( rearLeft);         wheels.push_back( rearRight);     }     const Wheel & getSpare(){ return spareInTrunk; }     void setSpare( const Wheel &newSpare ){ spareInTrunk = newSpare; }     // There are getters and setters for the other wheels too,     //but they aren't important for this example }; 

Then I'll see a function like this:

void wheelsRelatedToCar( Car *aCar, list< Wheel > &wheels ) {     aCar->wheelsOnCar( wheels );     wheels.push_back( aCar->getSpare() ); } 

This is a real example with the names of the classes and functions changed of course. Why would one want wheelsRelatedToCar to not be a member function of Car? In this real example, Car and Wheel were in the same library. The global function was defined in a source file in a specific application using that library, so the argument was made that the function was specific to the application. My response was that it was a perfectly legitimate operation on the Car and belonged with the Car class. Is there another perspective to look at it (other than one who does not prefer to use object oriented design)?

like image 828
Mutmansky Avatar asked Oct 28 '09 16:10

Mutmansky


People also ask

Under what circumstances should a member function be private?

Under what circumstances should a member function be private? The member function should be private when the function is needed for internal processing, but not useful to the program outside the class. In some cases a class may contain member functions that initialize member variables or destroy their contents.

When would you use a non member function?

Use a nonmember function if you don't need type conversion in the first argument or don't need access to private data. Use a member function if you do need access to private data.

Do all member functions need to be defined?

Although member functions can be defined either inside a class declaration or separately, no member functions can be added to a class after the class is defined. Classes containing member functions can have many declarations, but the member functions themselves must have only one definition in a program.

Why do we use member function in C++?

A member function of a class is a function that has its definition or its prototype within the class definition like any other variable. It operates on any object of the class of which it is a member, and has access to all the members of a class for that object.


1 Answers

Scott Meyers has advocated that non-member functions often improve encapsulation:

  • How Non-Member Functions Improve Encapsulation

Herb Sutter and Jim Hyslop also talk about this (citing Meyer's article) in "Self-Sufficient Headers"

  • http://www.ddj.com/cpp/184401705

These ideas have been republished (in more refined form) in the 3rd edition of Meyer's "Effective C++", "Item 23: Prefer non-member non-friend functions to member functions ", and Sutter/Alexandrescu's "C++ Coding Standards", "44 - Prefer writing nonmember nonfriend functions".

I think a lot of developers find this non-intuitive and maybe a little controversial.

like image 141
Michael Burr Avatar answered Oct 09 '22 06:10

Michael Burr