所以我有一个正在编写的基于插件的系统。用户可以创建一个Plugin类的子类,然后在运行时将其加载并与系统的其余部分集成。从系统运行插件时,它在一组插件的上下文中运行,我称之为会话。
我的问题是,在用户插件中,可以使用两个名为pf_ostream和pf_istream的流类来向系统读取/写入数据。我想以某种方式将插件实例的会话变量绑定到pf_ostream和pf_istream,以便用户实例化这些类时,它们已经为他们绑定了会话(基本上我不希望他们看到会话内部)
我可以使用宏完成此操作,将对构造函数的调用包装为:
#define MAKE_OSTREAM = pf_ostream_int(this->session)
但是我认为可能会有更好的方法。我看着在包装pf_ostream的Plugin中使用嵌套类,但是看起来嵌套类无法以一种封闭的方式访问封闭的类变量。
有人知道这样做的巧妙方法吗?
最佳答案
这是基于您在评论中提到的工厂想法的另一个答案。它使用Facade模式在绑定到System
的Session
类中集中创建系统设施:
#include <boost/shared_ptr.hpp>
class System
{
public:
typedef boost::shared_ptr<pf_ostream> pf_ostream_ptr;
typedef boost::shared_ptr<pf_istream> pf_istream_ptr;
// Other system facilities...
System(Session* session) : session_(session) {}
pf_ostream_ptr makeOstream()
{return pf_ostream_ptr(new pf_ostream(session_));}
pf_istream_ptr makeIstream()
{return pf_istream_ptr(new pf_istream(session_));}
private:
Session* session_;
};
class Plugin
{
public:
Plugin(System* system) : system_(system) {}
System& system() {return *system_;}
private:
System* system_;
};
class MyPlugin : public Plugin
{
public:
MyPlugin(System* system) : Plugin(system) {}
void print()
{
pf_ostream_ptr pfos( system().makeOstream() );
*pfos << "Hello World!\n";
// pfos will be deleted automatically at the end of this scope
}
};
如果您具有许多系统功能,则应明智地使用前向声明,以避免较长的编译时间。该解决方案的缺点是将系统设施集中在一个依赖项“焦点”(
System
类)中。如果System
类在使用了更多或更少系统设施的另一个应用程序中重复使用,则可能需要更改。编辑:
这是如何应用Proxy模式(以及Pimpl惯用语)以获取具有值语义的引用计数流类的方法:
#include <boost/shared_ptr.hpp>
class pf_ostream
{
public:
pf_ostream(Session* session);
pf_ostream& operator<<(int rhs);
// Use of default copy-constuctor and assignment operator
// will work fine because of shared_ptr.
private:
struct Impl;
boost::shared_ptr<Impl> pimpl_;
};
// In cpp file
struct pf_ostream::Impl
{
Impl(Session* session) : session(session) {}
void insert(int rhs) {/*...*/}
Session* session;
};
pf_ostream::pf_ostream(Session* session) : pimpl_(new Impl(session)) {}
pf_ostream& pf_ostream::operator<<(int rhs) {pimpl_.insert(rhs); return *this;}
用户将必须意识到代理对象的副本将引用相同的实际流。希望这可以帮助。