将包含头文件的库包含在单个cpp文件中

时间:2018-04-09 10:22:33

标签: c++

当我使用像Boost Spirit这样的大型标头库时,我经常希望将其包含隔离到单个cpp文件(parser.cpp)中, 为了减少所需的编译时间到一个文件。目标是当源文件(main.cpp)需要Spirit工具时, 它可以包含一个头文件,它向前端类提供 no 对任何Spirit内容的引用,让这个源文件快速编译。 只有一个cpp文件(parser.cpp)需要包含Spirit标头,并且需要更多时间来编译。

但是如何创建一个内部需要Spirit的类,而不在其声明中引用它? 我发现的唯一方法是使用指针成员到不完整的包装类(QiParser),然后在内部使用newdelete 创建真正的解析器。

我的问题是:有没有更好的方法来做到这一点,而不使用newdelete

以下是我现在使用的代码类型:

的main.cpp

#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;
}

parser.h

#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
};

parser.cpp

#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);
}

1 个答案:

答案 0 :(得分:0)

是的,请使用std::unique_ptr<QiParser> qi_parser;代替QiParser * qi_parser;。这被称为PImpl成语