Let's say I have 2 classes that I want to be visible (within a given header file) and one class that is their ancestor, which one I want to be visible only to the previously mentioned two. How can I achieve such class functionality of being invisible in C++?
It is not possible. C++ requires that a class be fully defined at the point it is used as a base, and because of its include mechanism anything that is fully defined at the point of definition of a class is necessarily visible to all who can see the definition of said class.
The class name or enumeration name is hidden wherever the object, function, or enumerator name is visible. This process is referred to as name hiding.
Simply put, data hiding in C++ is the process of hiding elements of a program's code from object members. The application will return an error if an object member tries to access concealed data. This is a safety feature that prevents the programmer from connecting to data that has been buried because it is incorrect.
Abusing a class
to act as a namespace
will do this. I do not recommend this pattern.
class hidden_stuff {
private: // hide base from everyone
struct base {
// contents
};
public:
class derived1;
};
typedef class hidden_stuff::derived1 derived1;
class hidden_stuff::derived1
: private hidden_stuff::base {}; // private inheritance required
// or hidden_stuff::base is accessible as derived1::base
A preferable solution would be to use a clearly-named namespace
such as impl::
or detail::
, which will convey to users that they shouldn't use any classes inside, and stop any possible undesired effects on overloading or the like. That's how most libraries (even Standard Library implementations) "hide" classes from the user.
It is not possible.
C++ requires that a class be fully defined at the point it is used as a base, and because of its include mechanism anything that is fully defined at the point of definition of a class is necessarily visible to all who can see the definition of said class.
C++ has mechanisms to protect against Murphy (accidents) but not against Machiavelli (hacks).
That being said, the purpose is itself dubious, the only reason I can fathom would be to prevent the user from relying on the fact that your Derived
class derives from this Fantom
base. Well, deriving privately: class Derived: private Fantom {};
or using composition instead class Derived { private: Fantom _fantom; };
would both achieve this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With