-1

There is one file with two separate classes and one function:

int foo(int x) {return x+x;}
class A {
    public:
    int bar(){return foo(0);} 
};
class B {
    public:
    int bar(){return foo(1);}
};

and they both need to use function

which uses only its argument (not use any data from A or B). I can declare this function as global. But i would like to hide this function for other files (so this is un visible, unacccesible in other files). So i can declare this function as member function of each class A and B. But this will be code duplicate.

What is the best practice for that?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
pi.314
  • 622
  • 5
  • 16
  • 3
    have you considered to implement this method in a base class and to make it protected and the two classes should implement this base class? – Buda Gavril Dec 11 '18 at 08:55
  • 1
    You want to "hide" it, in what sense? Do you want to prevent accidentally using it? Or are you trying to make sure that it's completely inaccessible? – D.Go Dec 11 '18 at 09:04
  • I like the idea of @BudaGavril and I'm waiting for him to answer. – Thomas Sablik Dec 11 '18 at 09:09
  • unvisible in other files, so there would not exist – pi.314 Dec 11 '18 at 09:09
  • 1
    You question does not specify whether the function must have private/protected and/or friended access to `A` and/or `B` members. If not, did you consider an anonymous namespace? – WhozCraig Dec 11 '18 at 09:09
  • 1
    Is there also one file that holds the implementations of `A` and `B`? Do you use this function in any inline member of `A` and `B`? You can't just slap `...` in your example and assume such information is not important. – StoryTeller - Unslander Monica Dec 11 '18 at 09:10
  • @WhozCraig The OP states *"they both need to use function which uses only its argument (not use any data from A or B)"*, so I guess you might expand that comment in an answer... – Bob__ Dec 11 '18 at 09:43
  • @pi.314 Regarding a wider view for maintenance and reusing implementation details, why are you trying to hide these as rigorously claimed for the function foo(). Why do you need to hide this implementation detail at all? – πάντα ῥεῖ Dec 11 '18 at 11:55

5 Answers5

4

You can just omit any declarations of foo from any headers, and mark it static or define it in an anonymous namespace.

AB.h

class A { int bar(); };
class B { int baz(); };

AB.cpp

static int foo(int x) { return x+x; }
/* or
namespace {
    int foo(int x) { return x+x; }
}
*/    


int A::bar() { return foo(1); }
int B::baz() { return foo(2); }
Jarod42
  • 203,559
  • 14
  • 181
  • 302
Caleth
  • 52,200
  • 2
  • 44
  • 75
1

You can simply place the function inside another class that only exists in that file:

class C
{
public:
    static void foo(int) {}
};

class A
{
    void test1()
    {
        C::foo(0);
    }
};

class B
{
    void test2()
    {
        C::foo(0);
    }
};

A & B can access this function now and it's not being declared globally.

You can also put the function in its own namespace:

namespace ABFunctions
{
    void foo(int) {}
}

And that is another way of keeping it separated, logically.

If you need to protect access, you can do it this way:

class C
{
friend class A;
friend class B;
private:
    static void foo(int) {}
};

class A : C
{
    void test1()
    {
        C::foo(0);
    }
};

class B : C
{
    void test2()
    {
        C::foo(0);
    }
};

Now, only class A & B will have access to foo(int).

D.Go
  • 171
  • 9
1

You can create a base class and derive from it. You won't have to duplicate code.

class Base {
    virtual ~Base = 0;
protected:
    int foo(int x) {return x+x;}
};

class A : public Base {...}
class B : public Base {...}

You can't instantiate an object of Base.

Thomas Sablik
  • 16,127
  • 7
  • 34
  • 62
0

If it does not use any data from A or B, then it probably shouldn't be implemented within A or B. It sounds as if f was some kind of auxiliary function. Perhaps creating a class Utilities and making it a public static function of the utilities class would be better.

Benjamin Bihler
  • 1,612
  • 11
  • 32
  • 1
    If he would do it global, than he can't hide it from another classes. – Buda Gavril Dec 11 '18 at 09:00
  • A `Utilites` class usually is an anti pattern as it contains many different methods and properties that don't belong together. – Thomas Sablik Dec 11 '18 at 09:04
  • Perhaps I got the question wrong. It is indeed unclear what "hiding" means. If usage should be prevented, then the utilities class could be a private nested class or it could have private static methods and declare A and B as friends. – Benjamin Bihler Dec 11 '18 at 09:10
0

In c++ there's no hiding of functions at namespace level, though you can create a utility class that contains only private static functions, and explicitly specify which classes may have access using the friend keyword:

class C {
   friend class A;
   friend class B;
   static void foo(int);
};

int foo(int x) {return x+x;}
class A {
    public:
    int bar(){return C::foo(0);} 
};
class B {
    public:
    int bar(){return C::foo(1);}
};

Though that's not a very good design pattern, since friend introduces some more maintenance effort, as soon other classes than A or B need to access foo as well.

A probably better pattern is to use an interface as I've sketched out in my Q&A here:

The introduction of interfaces there suffers from the overhead of virtual polymorphism though. Maybe that could be resolved with introduction of static polymorphism via the CRTP.


Regarding a wider view for maintenance and reusing implementation details, why are you trying to hide these as rigorously claimed for the function foo(). Why do you need to hide this implementation detail at all?

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
  • This is in my suggestion as well but I used `static` for `foo(int)`. I don't think there's a need to force an instantiation of the "extra" class. – D.Go Dec 11 '18 at 09:24
  • @D.Go Oops, I forgot to put the `static` keyword. Tho, I believe my way laid out in the linked Q&A is the better way to go. – πάντα ῥεῖ Dec 11 '18 at 09:27