最简单的解决方案是使用策略模式:定义一个Parser
带有纯虚函数的抽象基类,parse
并让派生类将指向其解析器实例的指针传递给基类构造函数;IE:
class Base
{
protected:
class Parser
{
public:
virtual ~Parser() {} // Probably not necessary, since no
// one is going to dynamically
// allocate any of these, but better
// safe than sorry.
virtual void parse( std::string const& data ) const = 0;
};
Base( Parser const& derivedClassParser, std::string const& data )
{
derivedClassParser.parse( data );
}
public:
// ...
};
每个派生类将定义其解析器,派生自
Base::Parser
,定义它的静态实例,并将该静态实例的地址向下传递给基类。
还有另一种可能;如果您有对象的临时实例,它不一定能正常工作,但如果由于某种原因您不能使用上述模式,它可能会很有用。基本上,您定义了一个特殊的类,该类在其析构函数中调用虚函数,并进行隐式转换std::string
(也可能从隐式转换char
const*
,以支持传递字符串文字),并声明您的构造函数以获取此类的实例;例如:
class Base
{
public:
class CallVirtual
{
std::string myData;
mutable Base* myOwner;
friend class Base;
public:
CallVirtual( std::string const& data )
: myData( data )
, myOwner( NULL )
{
}
~CallVirtual()
{
if ( myOwner != NULL ) {
myOwner->Parse( myData );
}
}
};
Base( CallVirtual const& dataArg )
{
dataArg.myOwner = this;
// ...
}
virtual void Parse( std::string const& data ) ...
};
派生类也应该接受一个CallVirtual const&
作为参数。然后,当您创建派生类的实例时:
Base* p = new Derived( someString );
,字符串会自动转换为临时CallVirtual
的,其析构函数将在完整表达式的末尾调用。