1

I refactor a code where a class has a friend function doing a lot of stuff.

class Foo
{
  friend void do_something(Foo& foo);
};

void do_something(Foo& foo)
{
  // More than 2000 lines of ugly code
}

I would like to split the content of do_something in several small functions. Something looking like this :

void do_something(Foo& foo)
{
  if(case_1) do_1(foo);
  else if(case_2) do_2(foo);
  else if(case_3) do_3(foo);
  //...
}

Is there a design where I can transfert the friendship to the sub-fuctions do_x(Foo&) without having to declare them in the class, or something similar in order to split the code ?

Note : C++11 only

Note : I don't want to write the sub-functions as maccros

Caduchon
  • 4,574
  • 4
  • 26
  • 67
  • 2
    `do_something` can access them and pass them as parameters to the subfunctions – 463035818_is_not_an_ai Apr 25 '22 at 08:26
  • 2
    Instead of calling e.g. `do_1(foo)`, call `do_1(foo.var1, foo.var2)`. – Some programmer dude Apr 25 '22 at 08:27
  • 2
    I'd say the question belongs there: https://softwareengineering.stackexchange.com/ rather than to SO... But on topic: what is the key factor that makes avoiding private functions worth it? Not expanding visible interface (guessing here)? I see several options here: 1. as @Someprogrammerdude has just written 2. using [PIMPL](https://stackoverflow.com/questions/8972588/is-the-pimpl-idiom-really-used-in-practice) to name the lowest hanging fruits. – alagner Apr 25 '22 at 08:30

1 Answers1

4

Instead of having do_something as function calling other sub-functions, I would suggest you to create an analogous class DoSomehting.

Then you could declare this class as a friend with friend class DoSomehting;. So these sub-functions could be its private methods. The method to call -- could be a public method named e.g. like void DoSomehting::process(Foo& foo):

class Foo
{
  friend class DoSomething;
};

class DoSomething
{
public:
    void process(Foo& foo)
    { 
        if(case_1) do_1(foo);
        else if(case_2) do_2(foo);
        else if(case_3) do_3(foo);
        //...
    }  

private:
    void do_1(Foo& foo);
    void do_2(Foo& foo);
    void do_3(Foo& foo);
};
JenyaKh
  • 2,040
  • 17
  • 25
  • Is there an advantage in doing this over the other suggestions made in the comments? Wouldn't `DoSomething` be stateless, in which case it doesn't really add anything. – Paul Sanders Apr 25 '22 at 08:38
  • Well, I think my answer solves the problem that you do not have to declare all the functions friends. Only one class. – JenyaKh Apr 25 '22 at 08:39
  • The solutions suggested in the comments don't propose declaring all the sub-functions as friends. – Paul Sanders Apr 25 '22 at 08:41
  • 3
    My solution is also a solution. The person who asked the question, can just choose a preferable one, I think. – JenyaKh Apr 25 '22 at 08:42
  • @PaulSanders the solution suggested in the comments is not easily scalable, for example, it `Foo` has private types or private member functions `do_something` needs, it would be a pain to transfer them to `do_1`. – n. m. could be an AI Apr 25 '22 at 08:51
  • @n.1.8e9-where's-my-sharem. Yes, I see it now, sorry Jenya. – Paul Sanders Apr 25 '22 at 09:14