Объявление пространства имен как друга класса
Мне было интересно, есть ли такой способ, чтобы все функции, определенные в определенном пространстве имен friend
, имели класс?
В частности, у меня есть класс, например:
class C {
private:
// ...
public:
// ...
friend C* B::f1(C*);
friend C* B::f2(C*);
friend C* B::f3(C*);
friend C* B::f4(C*);
friend C* B::f5(C*);
};
и пространство имен B
как:
namespace B {
C* f1(C* x);
C* f2(C* x);
C* f3(C* x);
C* f4(C* x);
C* f5(C* x);
};
Теперь я бы предпочел не писать 5 строк в определении класса, чтобы сделать все пять функций пространства имен B
friend с классом C
и просто сообщить компилятору, что все функции, определенные в пространстве имен B
являются друзьями класса C
(т.е. могут обращаться к своим частным членам).
Быстрое исправление, я думаю, это изменить пространство имен на класс и определить функции как его статические члены, а затем объявить класс B
как друга класса C
. Однако из любопытства мне было интересно, возможно ли такое с пространством имен или нет?
Спасибо заранее.
Ответы
Ответ 1
Нет, это не возможно подружиться с пространством имен. Если ничего другого, это будет представлять собой "нарушение безопасности", поскольку пространства имен могут быть расширены в любом месте. Поэтому любой может добавить произвольную функцию в пространство имен и получить доступ к непубличным данным класса.
Ближе всего вы можете найти решение, которое вы предлагаете, делая эти функции статическими членами класса и поддерживая класс. Но опять же, почему бы не сделать их статическими членами исходного класса (C
в вашем коде) в первую очередь?
В стороне, если я столкнулся с необходимостью для многих функций для друзей в моем коде, он снова подумает о моем дизайне; Я бы воспринял это как знак, что я делаю что-то неправильно.
Ответ 2
Если вы продвигаете свое пространство имен в класс, вы можете одновременно добавить несколько функций.
Он содержит (многие) другие недостатки, но вы действительно можете иметь класс B (по другим причинам).
class C {
private:
// ...
public:
// ...
friend struct B;
};
struct B {
static C* f1(C* x);
static C* f2(C* x);
static C* f3(C* x);
static C* f4(C* x);
static C* f5(C* x);
};