声明前向声明的类的成员函数作为朋友

hrr*_*hrr 13 c++ friend forward-declaration

是否可以将前向声明的类的成员函数声明为朋友?我正在尝试执行以下操作:

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(); 
};
Run Code Online (Sandbox Code Playgroud)

因此,目标是(i)将友元声明限制为单个方法,以及(ii)不包括复杂类的定义以减少编译时间.

一种方法可能是添加一个充当中间人的类:

// 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();
};
Run Code Online (Sandbox Code Playgroud)

然而,这似乎有点笨拙...所以我认为必须有一个更好的解决方案!

Xeo*_*Xeo 13

正如@Ben所说,这是不可能的,但你可以通过"密码"给予该成员函数特定的访问权限.它的工作方式有点像中间帮助程序类,但更清晰:

// 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());
  // ...
}
Run Code Online (Sandbox Code Playgroud)


Ben*_*igt 5

不,在声明之前,您不能将单个成员函数声明为朋友。您只能与整个班级成为朋友。