Say we have a class that has a private constructor, through friend
we can allow some specific class(es) to still create objects of this class:
class Foo
{
friend class Bar;
private:
Foo();
};
class Bar
{
Bar()
{
//create a Foo object
}
};
Now what if I want the opposite of friend
, where Foo
looks like this:
class Foo
{
//enemy/foe??? class Bar; (if only)
public:
Foo();
};
And then no method of Bar
can access the Foo
constructor/ make an object of Foo
but other classes can (because it's public
).
class Bar
{
Bar()
{
Foo foo; //compiler error
}
};
Is such a construct possible or am I stuck with keeping Foo
private and adding friends for all the classes?
A friend function can be declared in the private or public part of a class without changing its meaning. Friend functions are not called using objects of the class because they are not within the class's scope. Without the help of any object, the friend function can be invoked like a normal member function.
The friend function is declared using the friend keyword inside the body of the class. Friend Function Syntax: class className { ... .. ... friend returnType functionName(arguments); ... .. ... }
sure it does. It should work, so there must be a specific syntactic problem in the OP's code, or maybe a misunderstanding regarding how friendliness works.
friend functions A friend function is a function that isn't a member of a class but has access to the class's private and protected members. Friend functions aren't considered class members; they're normal external functions that are given special access privileges.
Such a thing does not exist, and it would be extremely pointless. Imagine you have a situation like this:
class Foo
{
enemy class Bar;
public:
Foo() {}
};
class Bar
{
void evil() { Foo{}; }
};
Nothing prevents the implementor of Bar
from doing this:
class Bar
{
void evil() { do_evil(*this); }
};
void do_evil(Bar &self)
{
Foo{};
}
do_evil
is not a member of Bar
(it's a global function), and so it's not an enemy. Such non-friendliness could therefore be trivially circumvented.
It cannot be done really, but maybe following is enough for you:
template <typename T> struct Tag {};
class Foo
{
public:
template <typename T>
Foo(Tag<T>) {}
Foo(Tag<Bar>) = delete;
// ...
};
And so asking "creator" to "identify" itself.
class Bar
{
Bar()
{
Foo foo{Tag<Bar>{}}; //compiler error
// Foo foo{Tag<void>{}}; // valid as we can cheat about identity.
}
};
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