Мне нужно убедиться, что функция C ++, объявленная другом определенного класса C ++, имеет внутреннюю связь.
Причина, по которой мне нужно, чтобы функция была другом, заключается в том, что ей нужен доступ к закрытому члену этого класса, частному члену, который кэширует результат функции.
Причина, по которой функция должна быть не членом (или, по крайней мере, не членом экземпляра) этого же класса, заключается в том, что другой код должен иметь возможность принимать указатель на функцию, не являющуюся членом. Рефакторинг это было бы слишком дорого.
Причина, по которой мне нужно иметь внутреннюю связь, заключается в том, что этих функций будет много, а в AIX их слишком много вызывает ошибку переполнения TOC при связывании. Это можно преодолеть с помощью -bbigtoc
переключатель линкера, но я пытаюсь избежать этого на данный момент.
Кроме того, я действительно хотел бы иметь возможность сохранить объявление класса в заголовочном файле, но поместить саму функцию в файл .cxx, который содержит реализацию.
Подводя итог, прямо сейчас у меня есть что-то вроде этого:
class Foo
{
private:
mutable Qux cachedBarResult;
// ... more code here ...
public:
friend const Qux & Bar(const Foo &);
};
const Qux & Bar(const Foo & foo)
{
if (foo.cachedBarResult.isEmpty())
{
foo.cachedBarResult = _worker_Bar(foo);
}
return foo.cachedBarResult;
}
static Qux _worker_Bar(const Foo & foo)
{
// real Bar work
}
я хочу сделать Bar
иметь внутреннюю связь. Это может быть сделано?
Да, вам просто нужно объявить прототип статической функции, прежде чем сказать, что это друг.
class Foo;
static const Qux & Bar(const Foo & foo);
class Foo
{
private:
mutable Qux cachedBarResult;
// ... more code here ...
public:
friend const Qux & Bar(const Foo &);
};static const Qux & Bar(const Foo & foo)
{
if (foo.cachedBarResult.isEmpty())
{
foo.cachedBarResult = _worker_Bar(foo);
}
return foo.cachedBarResult;
}
Других решений пока нет …