当我使用像Boost Spirit这样的大型标头库时,我经常希望将其包含隔离到单个cpp文件(parser.cpp
)中,
为了减少所需的编译时间到一个文件。目标是当源文件(main.cpp
)需要Spirit工具时,
它可以包含一个头文件,它向前端类提供 no 对任何Spirit内容的引用,让这个源文件快速编译。
只有一个cpp文件(parser.cpp
)需要包含Spirit标头,并且需要更多时间来编译。
但是如何创建一个内部需要Spirit的类,而不在其声明中引用它?
我发现的唯一方法是使用指针成员到不完整的包装类(QiParser
),然后在内部使用new
和delete
创建真正的解析器。
我的问题是:有没有更好的方法来做到这一点,而不使用new
和delete
?
以下是我现在使用的代码类型:
#include <iostream>
#include "parser.h"
int main (int, char **)
{
Parser p;
int n = 0;
p.parse("78", n);
std::cout << "The parsed number is " << n << std::endl;
return 0;
}
#include <string>
class QiParser; //< Incomplete class declaration
class Parser {
public:
Parser();
~Parser();
bool parse(const std::string &s, int &result) const;
private:
QiParser *qi_parser; //< The only way I found to not include
// the Spirit headers in this file
};
#include "parser.h"
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
// The QiParser class is only present to solve my problem;
// I would like to put this code directly into the Parser class, but without showing
// any Spirit stuff inside the parser.h header file
struct QiParser : qi::grammar<std::string::const_iterator, int()>
{
QiParser() : base_type(start)
{
start %= qi::int_;
}
qi::rule<std::string::const_iterator, int()> start;
};
// Implementation of the Parser class:
Parser::Parser()
{
qi_parser = new QiParser;
}
Parser::~Parser()
{
delete qi_parser;
}
bool Parser::parse(const std::string &s, int &result) const
{
auto iter = s.begin(), end = s.end();
return qi::parse(iter, end, *qi_parser, result);
}