C++项目组织示例(多头文件)和命名空间示例

版权声明:本文为博主原创文章,转载时请注明原作者,谢谢! https://blog.csdn.net/qq_31112205/article/details/84783447

        在上篇博客中展示的是单头文件的组织架构,而这篇博客将展示的是每个.cpp文件都有对应的.h文件。即.h文件定义它所提供的功能;.cpp包含.h文件用于实现。或许还需包含其他的.h文件,大项目大程序为了方便和整洁,会为了实现部分所用的interface(书中翻译为界面)放在另外的以_impl.h为后缀的文件里。其中就以parser._impl.h为例,如下图,箭头表示 使用 。

        在这里必须要着重说明的是parser_impl.h。为什么有了一个parser.h,还要一个parser_impl.h文件?这是为了尽可能的降低各个文件的相互依赖性,保证文件里的函数、变量等有最小的作用域。parser.h文件提供的是用户使用的interface,而parser_impl.h文件提供的是分析器的函数共享的环境。

        需要另外提一下的是,_impl.h的写法不是标准,也不是一种通用的约定,只是Bjarne Stroustrup所喜欢的命名方式。作为学习者可以参考这样的降低文件的相互依赖性的方式。

        在书中作者还提到parser.c使用了table.h。在它的处理上会有很多种的可能。可以放入parser_impl.h文件中;由于只有parser.c中的prim()需要table.h,可以放入一个新建的prim.c文件中(如下图所示);如果项目非常大,可以考虑又新建一个_impl.h文件。

        其各个文件代码如下(在这里.c和.cpp文件是一样的):

        由于每个文件的代码都很少,所以就把.h的文件放在一起,.cpp文件放在一起。

.h文件:

/*************************************************************************/

//error.h
namespace Error{
	struct Zero_divide{
	};
	struct Syntax_error{
		const char* p;
		Syntax_error(const char* q)
		{
			p = q;
		}
	};
}

/*************************************************************************/



/*************************************************************************/

//lexer.h
#include<string>

namespace Lexer{
	enum Token_value{
	NAME,        NUMBER,        END,
	PLUS='+',    MINUS='-',     MUL='*',     DIV='/',
	PRINT=';',   ASSIGN='=',    LP='(',      RP=')'
	};
	extern Token_value curr_tok;
	extern double number_value;
	extern std::string string_value;

	Token_value get_token();
}

/*************************************************************************/



/*************************************************************************/

//parser.h
//分析器的用户界面

namespace Parser{
	double expr(bool get);
}

/*************************************************************************/



/*************************************************************************/

//parser_impl.h
//分析器的函数所共享的环境

#include"parser.h" //将这个包含进来,是为了是编译器能检查一致性
#include"error.h"
#include"lexer.h"

namespace Parser{
	double prim(bool get);
	double term(bool get);
	double expr(bool get);

	using Lexer::get_token;
	using Lexer::curr_tok;
}

/*************************************************************************/



/*************************************************************************/

//table.h
#include<map>
#include<string>

extern std::map<std::string,double>table;

/*************************************************************************/

.cpp文件:

/*************************************************************************/

//lexer.cpp
#include"lexer.h"
#include"error.h"
#include<iostream>
#include<cctype>

Lexer::Token_value Lexer::curr_tok;
double Lexer::number_value;
std::string Lexer::string_value;

Lexer::Token_value Lexer::get_token()
{
	/*...*/
}

/*************************************************************************/



/*************************************************************************/

//parser.cpp
#include"parser_impl.h"
#include"table.h"

double Parser::prim(bool get){/*...*/}
double Parser::term(bool get){/*...*/}
double Parser::expr(bool get){/*...*/}

/*************************************************************************/



/*************************************************************************/

//table.cpp
#include"table.h"
std::map<std::string,double>table;

/*************************************************************************/



/*************************************************************************/

//main.cpp
#include"parser.h"
#include"lexer.h"
#include"error.h"
#include"table.h"

namespace Driver{ //可以将它分出来做成一个driver.h,并用#include包含进来
	int no_of_errors;
	std::istream* input;
	void skip();
}

#include<sstream>

int main(int argc,char* argv[])
{
	/*...*/
}

/*************************************************************************/

  它们的工程截图:

扫描二维码关注公众号,回复: 5037539 查看本文章

       总结,使用什么的组织架构看项目的大小以及个人的喜好。对于项目较小,可以使用单头文件的方式;对于大型的项目可以使用多头文件的方式实现,而多文件的文件划分的精细程度需要掌握好,太细难以管理,太粗糙出错debug难、后期维护复杂等。当然,单头文件和多头文件的方式并不冲突,在必要的时候可以结合的使用。

猜你喜欢

转载自blog.csdn.net/qq_31112205/article/details/84783447