Is it possible to declare a member function of a forward-declared class as friend? I am trying to do the following:
class BigComplicatedClass;
class Storage {
int data_;
public:
int data() { return data_; }
// OK, but provides too broad access:
friend class BigComplicatedClass;
// ERROR "invalid use of incomplete type":
friend void BigComplicatedClass::ModifyStorage();
};
So the goal is to (i) restrict the friend declaration to a single method, and (ii) not to include the definition of the complicated class to reduce compile time.
One approach might be to add a class acting as an intermediary:
// In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
// (...)
friend class BigComplicatedClass_Helper;
};
// In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
static int &AccessData(Storage &storage) { return storage.data_; }
friend void BigComplicatedClass::ModifyStorage();
};
However, this seems a bit clumsy... so I assume that there must be a better solution!
As @Ben says, it's not possible, but you can give specific access just to that member function through a "passkey". It works a bit like the intermediate helper class, but is imho clearer:
// Storage.h
// forward declare the passkey
class StorageDataKey;
class Storage {
int data_;
public:
int data() { return data_; }
// only functions that can pass the key to this function have access
// and get the data as a reference
int& data(StorageDataKey const&){ return data_; }
};
// BigComplicatedClass.cpp
#include "BigComplicatedClass.h"
#include "Storage.h"
// define the passkey
class StorageDataKey{
StorageDataKey(){} // default ctor private
StorageDataKey(const StorageDataKey&){} // copy ctor private
// grant access to one method
friend void BigComplicatedClass::ModifyStorage();
};
void BigComplicatedClass::ModifyStorage(){
int& data = storage_.data(StorageDataKey());
// ...
}