如果标题没有意义,这里是一个精简的例子。考虑一下这个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模式(以及monostate模式,虽然我不认为它与这个特定问题有关。)大多数它可以工作,但在这个特定的实现而不是其他,我必须创建一个信号处理程序,它必须是extern“C”函数而不是类的方法。如果代码设置如下,我会收到以下错误:
In function ‘void end_sig(int)’:
error: ‘myclass::myclassImpl myclass::_impl’ is private
我可以想出两种解决方法。
但在这两种情况下都会违反界面和实施的分离吗?还有更好的选择吗?
答案 0 :(得分:0)
您已经将信号处理程序与您的实现紧密耦合,因此我只想将其作为myclass
的朋友作为您的选项1。
另一个选择是在myclass
中创建一个公共清理功能,而根本没有友情。
答案 1 :(得分:0)
我推荐的方法是让end_sig
成为myclassImpl
的静态方法。它将具有C链接,因此可以传递给signal
,并且还可以访问任何必要的内部。不需要免费的朋友功能,它仍然隐藏在pimpl中。