如果标题不太有意义,这里有一个精简的例子。考虑这个 myclass.h:
// Compiled with g++ 4.7 and -std=c++0x -pedantic -Wall -Wextra on Linux
class myclass {
public:
myclass()=default;
void init();
private:
struct myclassImpl;
static myclassImpl _impl;
}`
和 myclass.cpp
#include <csignal>
using namespace std;
#include "myclass.h"
extern "C" {
void end_sig(int);
}
struct myclass::myclassImpl {
friend void end_sig(int);
myclassImpl()=default;
void cleanup();
}
myclass::myclassImpl myclass::_impl;
extern "C" {
void end_sig(int /* sig */) {
myclass::_impl.cleanup();
}
}
void myclass::init() {
signal (SIGINT, end_sig);
}
void myclass::myclassImpl::cleanup() {
// stuff...
}
如您所见,我正在尝试实现桥接或 pimpl 模式(以及单态模式,尽管我认为它与这个特定问题无关。)大多数情况下它都有效,但在这个特定的实现中而不是其他的实现中,我必须制作一个信号处理程序,它必须是外部“C”函数而不是类的方法。如果代码是这样设置的,我会收到以下错误:
In function ‘void end_sig(int)’:
error: ‘myclass::myclassImpl myclass::_impl’ is private
我可以想到两种解决方法。
- 将朋友声明移到 myclass 中。
- 公开 _impl。
但是在这两种情况下,它都会违反接口和实现的分离吗?有没有更好的选择?