0

I have written a program, which takes an input vector of integers and prints all possible permutations of these integers.

In order to do that my program has two methods: void Permutate(//input) and void DoPermute(//necessary arguments) Only the method Permutate should be called by the user/client. DoPermutate is a recursive method which is firstly called by Permutate and provides the logic for the algorithm. The question now: would you put Permutate and DoPermutate in a class and make DoPermutate private, or would you put both methods in the global scope and not use classes at all and thus expose DoPermutate to the user/client? I am asking this because cmath also has the utility methods in a global scope. What would be a more elegant approach?

Stefan B
  • 541
  • 2
  • 6
  • 13
  • 5
    I assume this is for a school assignment or similar? Because otherwise you could just use [`std::next_permutation`](http://en.cppreference.com/w/cpp/algorithm/next_permutation). – Some programmer dude Oct 22 '17 at 19:38
  • 2
    You do know that [std::next_permutation](http://en.cppreference.com/w/cpp/algorithm/next_permutation) already exists, right? – Jesper Juhl Oct 22 '17 at 19:38
  • 2
    General rule of thumb is If the function doesn't require any state information that isn't provided as a parameter, don't put it in a class. – user4581301 Oct 22 '17 at 19:43
  • I am asking this mostly for education purposes. This concept of algorithms that use helper methods can be applied for a variety of problems, e.g Mergesort and Quicksort. I am mostly curious about which style is more elegant when dealing with these 2 method algorithms: Use a class and hide logic or not using classes and expose the helper method. – Stefan B Oct 22 '17 at 19:45
  • 1
    @user4581301 Sometimes a class is a useful organizational structure for encapsulating an algorithm if you're using a design pattern that requires passing these around. Normally you'd write a sort algorithm as a straight-up function, but if you take a different approach you could pass around an instance of an object derived from an abstract base which defines the operations it can perform. Not always a clear-cut line here. These classes tend to be super tiny, often little more than a pointer, which makes them pretty cost-effective. – tadman Oct 22 '17 at 19:48
  • 1
    If you want to hide `DoPermutate` consider using an [anonymous namespace](https://stackoverflow.com/questions/357404/why-are-unnamed-namespaces-used-and-what-are-their-benefits) – user4581301 Oct 22 '17 at 19:48

1 Answers1

1

The question now: would you put Permutate and DoPermutate in a class

This is what I would to:

  1. Declare Permutate in a namespace, such as:

    namespace MyApp
    {
       // Declare
       void Permutate( ... ); // Add all the necessary arguments,
                              // which can be input arguments ad
                              // output arguments.
    }
    

    Please note that the declaration does not expose whether a class is used in the implementation. That is detail of the implementation that does not need to be exposed in the interface.

  2. If it is helpful to use a class in the implementation, use it.

    namespace MyApp
    {
       // Helper class
       struct PermutateClass { ... };
    
       // Implement the user facing function.
       void Permutate ( ... )
       {
          // Delegate the implementation to the helper class.
          PermuateClass p(...);
          p.doIt();
       }
    }
    
  3. If it is not helpful to use a class, just use helper functions as needed.

    namespace MyApp
    {
       // Helper function
       void DoPermutate ( ... ) { ... }
    
       // Implement the user facing function.
       void Permutate ( ... )
       {
          // Delegate the implementation to the helper function.
          DoPermutate p(...);
       }
    }
    

The key point I want to emphasize is that whether you use a helper class with a bunch of member functions or a bunch of non-member function is an implementation detail that you should be able choose without impacting the users of the user facing function.

R Sahu
  • 204,454
  • 14
  • 159
  • 270