12

I'm writing a linear algebra library (long story short, it's a school assignment) that involves matrices, vectors, etc. In the process of creating this library, I'm going to be creating functions that perform mathematical operations on objects. For example, transpose matrix, invert matrix, normalize vector, etc.

I was curious as to what is the "best practice" for this sort of function... That is, should I make the function a member function, or non-member? (For clarity/library use sake)

Example:

//Member function way:
B = A.transpose();
C = A.inverse();

//Non-member function way:
B = linalg::transpose(A); //Non-member transpose function in linear algebra namespace
C = linalg::inverse(A);

Is there some standard regarding these sorts of operations? Or, at least, is there a common way people do this? I'm leaning towards the first option, but I'd like to know if this is recommended.

7

This is just a matter of style and taste. I have seen different linear algebra libraries, either

  • written in an OOP style using member functions

  • written in a non-OOP style using only free functions

  • providing an API with both

and all of them were working. At least, your API should be consistent, so pick your choice and make sure you don't mix those styles arbitrarily.

8

Avoid membership fees: Where possible, prefer making functions nonmember nonfriends.

Nonmember nonfriend functions improve encapsulation by minimizing dependencies: The body of the function cannot come to depend on the nonpublic members of the class (see Item 11). They also break apart monolithic classes to liberate separable functionality, further reducing coupling (see Item 33). They improve genericity, because it's hard to write templates that don't know whether or not an operation is a member for a given type [...]

Herb Sutter

1

Both member and non-member functions have real advantages besides mere taste. For example, the underlying array(s) used to implement a matrix class will probably be private, therefore, you will have to use friend unless you use member functions. In this respect, an OO design may be better.

However, keep in mind that, from time to time, computer scientists have to implement complex math formula without always knowing what thy really do. When I have to do so, I prefere non-member functions since the "visual" result will be closer to the original math formula (since math formula generally use a functional style).

In the end, the answer is the same as Doc Brown's one: it's a matter of taste. In short, you could consider writing an OO-style library with member functions (easier to write, no friend), then writing non-member functions to do the same tasks which will simply forward their arguments to the member ones. It allows you to be consistent and to let the user choose what he thinks is best.

0

If you dive deeper in your problem statement, it is clear that at some point you'll use custom data structures that represent certain mathematical entities. For instance, you might represent a matrix my means of a n-dimensional array. To elaborate on your example,

// C way
typedef struct {
    int data[MAX_LEN][MAX_LEN];
} MATRIX;

MATRIX B = transpose(A);

// C++ way
class Matrix; // Forward Declaration
class Matrix {
    int data[MAX_LEN][MAX_LEN];
    public:
        Matrix transpose();
};

Matrix B = A.transpose();

(The C++ example is simplified, you can use templates and such.)

The point to consider is the ease of using custom data structures in both cases. C++ (or any object oriented) as a language is more powerful in itself, and that extends to the consumer of the library as much as it benefits the implementer. I've used C only libraries in the past and those custom data structures seem to get all over the place in no time! Whereas interoperability is easier to achieve with the latter (using special constructors, maybe?)

To wind it up, if you're using C++ then a object oriented approach is definitely recommended.

  • 5
    Sorry, there's very little solid fact in your reasoning. There's no difference in ease of use between your two transpose examples. The main reason C++ ie easier is because copy and assignment semantics actually work. A = B may compile in C but probably does the wrong thing. – MSalters Feb 25 '14 at 11:18
  • +1 for copy semantics The point I was trying to get across is using objects (encapsulations over "representations") v/s using loosely coupled set of structures and related functions. – dotbugfix Mar 1 '14 at 6:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.