Extract common blocks in functions in C ++

There is something that I constantly encounter while working on C ++ code.

Say I have a method that does X, Y, and then Z. Now I would like to introduce another method that should do X, Y ', Z. If it were a plain old C code, I would then make X functions ( ) and Z () with common code, declaring them static , so that the compiler can now be embedded if necessary, since the code cannot call them from this “module”. A method that will be part of the API will look like

 int M(args) { X(foo); // that could eg be "check args are valid". /* here comes M-specific code */ Z(bar); // that could eg be "update_state" } int M2(args) { X(foo); /* here comes M2-specific code */ Z(bar); } 

Now, if I do the same in C ++, X () and Z () no longer have access to the class' protected / private members. Switching between .h and .cc files to declare these “helpers” X () and Z () when I start writing code somehow tempts me to just copy / paste the common code instead, so I try to duplicate the class, having something that is closer to the (java) interface in .h - with virtually no member variables, and then have variables, API methods, and “helper” methods in the class block in the .cc file, which inherits from the “interface” .

However, I doubt this is good practice with C ++, so I am curious to know what other people do in this case.

+4
source share
5 answers

If X and Z do things related to the class, then they make them member functions of the class (and if not, then there is no problem, since their implementation can be easily found elsewhere, outside of public opinion).

If they should not be part of the public interface of the class, make them private .

If you are worried that their function signatures appear in the class definition, then there are several ways to restructure your code so that implementation details are not shown.

A common way, for example, is to use the Pimpl idiom .

Another way would be to expose the (abstract) interfaces in the public API and hide the implementation classes from the view. This is not always possible, but when it is, it can be very effective.

+3
source

If I understand that you are right, what you want to achieve is to write two functions X () and Z () only once for more than one function M (). Like other comments, offer them member functions marked as inline.

In addition to implementing X () and Z () as member functions, I would use a strategy template where you have a function M () like this

 class ClassTest { private: void X(); void Y(); Alogrithm* m_algorithm; public: void M(); void setAlgorithm( Alogrithm* a ) { m_algorithm = a; } } void ClassTest::M() { X(); m_algorithm->execute(); Z(); } 

This eliminates the need for a second function M2 (). You only need to set the setter for m_algorithm, which is a small object that implements your original Y () function. Thus, the algorithm can even change the execution time.

+1
source

You can move the functionality of X and Z to a private member function of your class and mark them with the inline modifier if you want. This would allow access to private members, making it difficult to access from outside the class.

0
source

I think you are mistaken from the concepts:

  • If X() and Z() have common code, this is an improvement in design. Refactor them.
  • If M1(args) working fine, why are you changing it? After refactoring X() and Z() you can use them in a different way. Just create M2(args) with the new X() and Z() plus the new functions in the new Y() method.
0
source

You can do the following functions:

  • Make them private members of the class.
  • Or you can put them in an anonymous namespace in the implementation file.

With parameter No. 2, you cannot access private members of the class, while this is a big problem, you can mitigate it by passing all (and only) the required parameters and either returning the value or using the output parameters (pointers or links).

0
source

All Articles