将前向声明类的成员函数声明为友元
Declare a member-function of a forward-declared class as friend
是否可以将前向声明类的成员函数声明为友元?我正在尝试做以下事情:
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();
};
因此,目标是(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();
};
然而,这似乎有点笨拙。。。所以我认为一定有更好的解决方案!
正如@Ben所说,这是不可能的,但您可以通过"passkey"授予对该成员函数的特定访问权限。它的工作方式有点像中间助手类,但更清晰:
// 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());
// ...
}
不,在声明单个成员函数之前,不能将它们声明为友元。你只能和全班同学交朋友。
这里可能相关,也可能不相关,但提醒我们自己,在类和对象的范围之外,还有一个狂野的世界,函数可以自由漫游。
例如,我最近需要从一个基于他人代码端口的全局异常处理程序中关闭一个(单例全局静态)系统错误日志。错误日志的正常包含文件与异常处理程序代码冲突,因为两者都希望包含"windows.h",原因我没有研究。当这个问题和其他问题说服我,我不能对ErrorLog类的成员函数进行正向声明时,我所做的是将必要的函数包装成一个全局范围函数,如下所示:
void WriteUrgentMessageToErrorLog( const char * message )
{
ErrorLog::LogSimpleMessage( message );
ErrorLog::FlushAccumulatedMessagesToDisk();
}
有些人非常注重不惜一切代价保持阶级结构的完整性。。。很少承认使用这些类的应用程序不可避免地建立在缺乏这种结构的基础上。但它就在那里,而且使用得当,它有它的位置。
考虑到这个问题的年龄,我没有深入研究它在这里的相关性。我想分享的是这样一种观点,即有时像这样简单的包装机制是一种更干净、更容易理解的替代方案,而不是一种更微妙、更聪明的东西。微妙和聪明往往会在以后的某个日期被不完全理解它的人要求添加到它中。在你意识到它之前,你有一个错误。。。
相关文章:
- C++:为什么允许在另一个函数中声明函数,而不允许在函数定义中声明?
- 在c++中在类外声明函数有什么好处
- 使用 #define 声明函数
- 在静态库中声明函数,在使用该相同库的应用程序中定义它
- 如何强制编译器在 C/C++ 本身中声明函数?
- 如果您只需要在 .h 文件中声明函数.cpp是否需要在 .h 文件中声明函数?
- C++:<sys/sysctl.h> 无法声明函数CTL_HW和HW_NCPU
- 尝试声明函数的局部变量,但得到范围错误
- 如何在C++模板中声明函数
- 如何在另一个文件的类中声明函数
- 使用非类型模板参数正向声明函数模板
- 在此范围错误中未声明函数错误
- 当我们不能声明函数内联(GCC 编译器)时?
- 未在此作用域中声明函数,即使存在头文件也是如此
- 无法声明函数中的模板类型别名
- 单个CPP文件中多次声明函数声明可以吗?
- 编译一个支持VBA中声明函数的dll
- 使用从外部参数包中获取的参数类型声明函数
- 使用类成员正确地声明函数
- 在函数内重新声明函数