For example, Let's suppose there are "a.h", "b.h" and "source.cpp"
// file: a.h
int functionA(int value) {
...
return something
}
a.h is the header file. b.h uses functionA from a.h
// file: b.h
#include "a.h"
class className {
public:
int functionB(const int & val) { // functionB uses functionA
return functionA(val);
}
};
// file: Source.cpp
#include "b.h"
int main() {
className obj;
obj.functionB(); // All good But,
functionA(); // I don't want main to access a.h's function
return 0;
}
I don't want the Source file to access a.h's functions. Is there any way to restrict source.cpp from accessing functions from a.h
Here's what I've been trying to do. Consider ComplexNumbers.h and main.cpp
// ComplexNumbers.h uses <cmath> header's function
#include <cmath>
namespace math {
class ComplexNumber {
private:
double real, imag;
public:
ComplexNumber(double r, double i) {
real = r;
imag = i;
}
double getArgument() { // returns the angle made by the complex number with x-axis
return atan(imag/real); // Uses function from <cmath>
}
}; // class ComplexNumber
} // namespace math
// Main.cpp
#include "ComplexNumbers.h"
#include <iostream>
using namespace std;
int main() {
math::ComplexNumber z(1,2); // Obj, All good But,
cout << atan(1) <<'\n'; // atan() function also works in main.cpp
return 0;
}
I don't want main.cpp to access <cmath> function via ComplexNumbers.h. Is there any way that the <cmath>'s function only gets used in ComplexNumbers.cpp rather than main.cpp
Is there any way to restrict
source.cpp
from accessing functions froma.h
Not without some significant changes to your code. Headers are "copied and pasted" into the file that #include
s them, and there is no way to make portions of them inaccessible.
To solve this, you could be using C++20 modules, which only make export
s visible, and allow you to import
other modules without making the imported contents visible to other modules. However, C++20 modules are still somewhat unstable, and they're not supported by clang, so you might not want to use them.
In your case, this would require import <cmath>
instead of #include <cmath>
, and would have the desired effect.
A "bandaid" solution that people typically use is a "detail namespace":
// file: a.h
namespace detail {
int functionA(int value) {
...
return something
}
} // namespace detail
// file: b.h
#include "a.h"
class className {
public:
int functionB(const int & val) {
return detail::functionA(val);
}
};
However, this doesn't prevent someone from using detail::functionA
when they include b.h
, it just makes it so they don't accidentally use it, and the function won't show up for auto-completion.
In the context of <cmath>
, you cannot do this, because you don't control what namespace the functions in <cmath>
are in.
You might also be able to solve this by implementing functionB
in a source file. If you did that, then #include "a.h"
would no longer need to appear in b.h
:
// b.h
class className {
public:
int functionB(const int & val);
};
// b.cpp
#include "b.h"
#include "a.h"
int className::functionB(const int & val) {
return functionA(val);
}
In the context of <cmath>
, this would require implementing member functions of ComplexNumber
in a source file, which is extremely undesirable because it prevents inlining and constexpr
.
In conclusion, there are some solutions, but all of them have major downsides. However, it's not that bad to "leak" the #include <cmath>
into headers which use complex numbers. It's likely that users would have included the math library themselves.