2023-4-4-C++应该怎么设计一个好的项目结构



*★,°*:.☆( ̄▽ ̄)/$:*.°★*

欢迎来到汤姆的csdn博文
喜欢的朋友可以关注一下,下次更新不迷路
私聊获取个人订阅号哦,欢迎订阅共同学习
可以加入大家庭群聊,一起学习天天有福利





本文摘要

在这里插入图片描述
本人也是一个C++迷,作为一名C++程序员我的目标就是成为一名高级C++架构师,与此同时我会通过不断地学习最终实现我的目标。作为一个幸运儿,我受到身边大佬的影响在编程生涯正式开始的阶段养成了比较良好的编程风格和项目目录的管理。在工作和生活中也接触过Java工程和Python工程,每一个语言都有属于其不同的项目架构,这篇文章主要是探索学习一下一个好的C++的项目架构应该是什么样子的,程序员应该如何去管理项目。欢迎与我同样有兴趣了解C++架构的小伙伴一起学习一下,如果感觉作者写的不错欢迎点赞评论加关注,后续还会有更多的学习分析,接下来让我们撸起袖子加油干!


目录

  • 本文摘要
  • 一、单个文件如何设计结构
  • ‍二、复杂的工程如何设计结构
  • 文章总结



一、单个文件如何设计结构

作为一名程序员,要时刻记住一句话,那就是“程序是写给程序员的”。这个程序员可以是测试,可以是基于你写的代码继续开发的同事,更可能是你未来的自己。如果你的项目文件之间引用混乱,文件与文件之间的逻辑“错综复杂”到最后一定会造成可想而知的几个结果:

  • 测试人员让你改BUG的时候你花了大量的时间回顾了自己之前写的代码。
  • 你有事想请假的时候领导让别人完成你未完成的开发任务,结果你的同事看不懂你的代码,疯狂的call你。
  • 你进行应用升级的时候或应用迭代的时候,你为了兼容之前错乱的写法继续采取了错误的写法,然后写出了更错乱的代码,然后长此以往陷入了恶性循环。

如果要尽量避免出现上述问题,就要在日常的编码中时刻注意自己的规范,将代码写的规范些会给自己避免很多问题,将一位大佬对我曾说过的话跟大家分享“要把代码放在它应该放到的位置”。

区别对待.h和.cxx
C++是面向对象的一门语言,它具有类的概念,在你新建一个类的时候,大多数编译器会自动地给你生成名称相同的两个文件,一个.h文件,一个.cpp文件,也就是我们常说的头文件和源文件。

2023-4-4-C++应该怎么设计一个好的项目结构_第1张图片

在编程过程中建议程序员一定要区别对待这两种文件,只在头文件里放置声明,包括类的声明,函数的声明,变量的声明,而它们的实现就全部放置到源文件里面。这是一种编码风格,是一种程序员之间心照不宣的写法,这样的编程风格有助于代码条理的清晰,让阅读者读起来比较方便。“声明”向计算机介绍名字,它说,“这个名字是什么意思”。而“定义”为这个名字分配存储空间。无论涉及到变量时还是函数时含义都一样。无论在哪种情况下,编译器都在“定义”处分配存储空间。对于变量,编译器确定这个变量占多少存储单元,并在内存中产生存放它们的空间。对于函数,编译器产生代码,并为之分配存储空间。函数的存储空间中有一个由使用不带参数表或带地址操作符的函数名产生的指针。定义也可以是声明。如果该编译器还没有看到过名字A,程序员定义int A,则编译器马上为这个名字分配存储地址。
声明常常使用extern关键字。如果我们只是声明变量而不是定义它,则要求使用extern。对于函数声明, extern是可选的,不带函数体的函数名连同参数表或返回值,自动地作为一个声明。

在完成类的声明包括其中成员函数和成员变量的定义之后,一定要在头文件中加入条件编译语句
2023-4-4-C++应该怎么设计一个好的项目结构_第2张图片

小知识
为什么要加条件编译语句:加条件指示符的最主要目的是防止头文件的重复包含和编译
在c语言中,对同一个变量或者函数进行多次声明是不会报错的。所以如果h文件里只是进行了声明工作,即使不使用# ifndef宏定义,多个c文件包含同一个h文件也不会报错。
但是在c++语言中,#ifdef的作用域只是在单个文件中。所以如果h文件里定义了全局变量,即使采用#ifdef宏定义,多个c文件包含同一个h文件还是会出现全局变量重定义的错误。而#ifndef作用域是全局的,使用#ifndef可以避免上面所说的全局变量重定义的错误

#ifndef x                 //先测试x是否被宏定义过
#define x
   程序段1    //如果x没有被宏定义过,定义x,并编译程序段 1
#endif   
  程序段2   //如果x已经定义过了则编译程序段2的语句,“忽视”程序段 1

小知识
C++项目的编译原理:在编译的时候编译器编译的是项目的cpp文件,头文件是不能被编译的。“#include”叫做编译预处理指令,可以简单理解成,在cpp中的#include指令把对应h中的代码在编译前添加到了cpp中代理掉了Include这条语句。每个cpp文件都会被编译,生成多个obj文件,然后所有的obj文件链接起来就是最终的可执行程序。

为当前文件定义namespace命名空间,建议根据文件路径以及已有命名空间进行镶嵌定义,注意不要使用std这种已经命名空间,否则会留下很多隐患
2023-4-4-C++应该怎么设计一个好的项目结构_第3张图片

小知识
为什么定义命名空间
所谓命名空间,是一种将程序库名称封装起来的方法,它就像在各个程序库中立起一道道围墙,或者说指定了很多同名的孩子(变量)的归属,因为随着C++的不断发展,关键字和变量越来越多,在工程中使用有遇到重命名的问题越来越多,所以引入了命名空间,让每一个即使是同名的变量都可以辨识。
命名空间可以定义在几个不同的部分中,因此命名空间是由几个单独定义的部分组成的。一个命名空间的各个组成部分可以分散在多个文件中。所以,如果命名空间中的某个组成部分需要请求定义在另一个文件中的名称,则仍然需要声明该名称。

冷知识
有时我们并不希望命名空间被局部的环境之外知道,此时名字似乎多余了,因此我们可以省去这个名字 直接改写为:
namespace
{
int a;
}
定义无名命名空间后,外部即不能得知无名命名空间的成员名字,即不让外部知道我的成员名字及其调用
由于没有名字,所以其它文件无法引用,它只能在本文件的作用域内有效,
它的作用域:重无名命名空间声明开始到本文件结束。在本文件使用无名命名空间成员时不必用命名空间限定。其实无名命名空间和static是同样的道理,都是只在本文件内有效,无法被其它文件引用。

如果你的代码中应用到了其他的命名空间的变量或者方法,这时候需要using一下
2023-4-4-C++应该怎么设计一个好的项目结构_第4张图片
我不建议在头文件中使用 using namespace xxx 语句,不仅是对std空间。如果头文件a.h使用了该语句,那么所有与a.h有关系的文件都会默认使用该语句,也就是说引用a.h头文件的都被迫using了,所以引用头文件的越多就会越容易导致命名冲突。所以当我们在写成熟的代码的时候,需要用库里的什么就打开什么。这就有效的防止了命名冲突。
对于使用自己定义的其他命名空间,建议学习上文中的这种写法,用using=…的方式能够缩小命名空间的存在范围,可以进一步避免命名冲突的问题出现。

小知识
什么是std:std::是个名称空间标识符,C++标准库中的函数或者对象都是在命名空间std中定义的,所以我们要使用标准库中的函数或者对象都要用std来限定。

以上就是目前我在C++开发中对于单个文件的结构设计,如果有更好的建议希望读者能够在评论区中分享。


‍二、复杂的工程如何设计结构

对于如何设计一个好的项目结构本身是一件仁者见仁智者见智的事,如果是自己的项目自己玩那怎样设计无所谓,自己开心就好,文件放在什么目录下,目录的名字叫什么都可以,但是如果是一个很多人都会参与的工程,很多人都会使用的工程,那么就必须要有一个清晰的工程结构方便大家,泪目了。

以下是我在整理出来的项目于结构,也是参考了很多大型开源项目的工程结构又进行了调整,最终的结构如下图所示,该工程是一个Cmake工程所以会有一个CmakeLists.txt。
2023-4-4-C++应该怎么设计一个好的项目结构_第5张图片

该目录结构如上图所示
cmake-build-debug-visual-studio=该项目用VS编译后的可执行文件所在
dist=可部署项目,其中包括各种环境依赖的安装包,包括工程跑起来所需要的exe和dll等
doc=该工程的一些说明文件或者有关该工程的一些说明文档
examples=该工程的一些示例工程,简单的demo
include=该工程的头文件所在的目录
lib=该工程依赖的一些开源库的dll所在的目录
res=该工程以来的一些图片资源或者其他资源
src=该工程的源文件所在的目录
test=该工程的测试工程所在的目录
thirdparty=该工程依赖的一些开源库的头文件或者源文件所在目录
tools=该工程提供的工具包,可以是一些非常好用的工具


文章总结

提示:这里是文章总结:

  本文讲了关于C++如何设计单文件的结构以及如何设计项目结构,希望小伙伴有所收获,一个好的项目结构对开发起着事半功倍的作用,希望读完这篇文章的伙伴们可以分享一下对文章的意见和建议,可以通过评论或者私信的方式与我交流哈






更多好文推荐

2021-4月Python 机器学习——中文新闻文本标题分类
2021年4月-(计算机网络)小型校园网络模拟搭建,最全最准确版
2022-10-31-基于用户的协同过滤推荐算法实现+MAE+RMSE
2022-11-28-大数据可视化,特征维度大于50
2023-3-9-一篇简短的文章把C++左右值关系讲的透透彻彻

上一篇
End
下一篇

你可能感兴趣的:(汤姆C++系列,c++,开发语言)