如何将包含大量类的一个文件转换为每个文件一个类的多个文件? (C \ C ++)
所以我有这样的结构的文件:有些包括,然后很多有时互相调用的类:
#include <wchar.h>
#include <stdlib.h>
//...
class PG_1 {
//...
}
class PG_2 {
//...
}
//......
class PG_N {
//...
}
答案 0 :(得分:4)
如果您没有使用版本控制(tsk tsk):
classname.h
和classname.cpp
文件中。将classname
替换为类的名称。更新包含警卫。#include
指令。multiclass.h
和multiclass.cpp
。#include
)并转到步骤6. 如果您使用的是支持文件级分支的修订控制系统(例如Perforce,或者Subversion?),您应该注意保留修订历史记录,以便其他开发人员可以找到旧的更改:
multiclass.h
和multiclass.cpp
中的每个班级名称,请将multiclass.h
和multiclass.cpp
整合到该班级的单独classname.h
和classname.cpp
中。 #include
指令。multiclass.h
和multiclass.cpp
是否已删除。#include
)并转到步骤10. 如果您使用的是不支持文件级分支的修订控制系统,那么这两种方法的某些组合应该可以使用。希望你明白了。
答案 1 :(得分:2)
如何使用大量文件来翻转一个文件 具有一个类的许多文件的类 每个文件?
编辑:关于一般的重构,我应该提一下。重构中没有重要的一步(除非你想破坏你的代码库)。您应始终对代码进行事务转换,并在其间进行有效性检查(事务性意味着它们明确分隔,并且可以在任何时候提交和回滚)。如果你有很大的步骤意味着你没有将它们分解成小步骤。此外,每一步都应该做一件事,一件事。 (结束编辑)。
步骤:
备份所有内容(所有受影响的文件)
这意味着在源代码管理系统中执行提交。如果您不使用任何源代码控制,请在继续之前安装mercurial(继续,我们将等待;)) - 您可以稍后再次感谢我:D
为要删除的第一个类创建新文件(.h和.cpp文件),然后在旧标题中包含新的.h文件(具有多个类的文件)。
< / LI>移动.h文件中的类声明和新.cpp文件中的类实现。
从旧文件中删除声明/实现。此时编译代码,并将#include
dirrectives从旧文件复制到新文件,直到所有内容编译。此时,您应该将您的类移动到单独的文件,并包含在旧的头文件中。不要复制所有包含,只能让您移动的类正确编译。
编译代码(最终运行应用程序并确保一切运行)。
在源代码管理系统中执行提交。
从旧(多个类)头文件中删除包含的新文件并进行编译。浏览代码并将新文件包含在您收到错误的任何文件中。
重复步骤5和6.
选择新课程,返回第1步。
可能出现的错误和警告:
您可能会在将新代码移动到新文件时对其进行其他更改。 不做任何更改。在循环结束时(在步骤8之后),您应该具有与步骤1之前相同的代码,只需在不同的文件中。您在步骤之间对代码所做的任何更改将难以与重构分离,以后难以跟踪且难以反转。这不值得麻烦,特别是当重构周期完成后你可以做出相同的改变(没有其他问题)。
您可能想要同时处理多个课程。不要这样做。如果您在循环中工作,您始终可以将代码(在SCM中)还原为有效的代码版本,并且您可以进行模块化更改。如果你一次上一堂课,也可以很容易地跟踪变化并检查你是否没有引入新的错误。
Sidenote :如果您使用分支SCM,您将能够并行处理任务,中断您的重构(提交所有内容 - 让我们称之为“分支头A”),返回在开始重构之前的代码,进行一些其他更改,提交它们(称之为“分支头B”),然后返回分支头A,完成重构,然后合并A和B,你就可以了。< / p>
答案 2 :(得分:1)
有几种方法可以实现这一目标。
最直接的方法是一次读取一行文件并检测该行是否开始上课。
然后开始检测匹配的括号...你知道如果你找到{
+1和}
-1,直到你达到零。是的,还有更多,但这是主要部分。
选择该块并将其写入另一个文件。
另一方面, IF 你正在使用Visual Studio,就是创建一个宏并使用DTE
来仔细阅读当前打开文件的FileCodeModel
,并为其中的每个顶级类创建一个文件。
答案 3 :(得分:0)
你知道如何手动完成吗?如果你知道,编写一个程序来做同样的事情是很简单的。
答案 4 :(得分:0)
可能没有简单的方法可以做到这一点。问题是你必须让#include
正确,将代码正确地拆分到不同的头文件和cpp文件,如果你的类之间有循环依赖关系,你必须正确处理它们,或者更好,尝试解决这些依赖关系,使它们成为非循环的。
最佳建议我可以给你:首先尝试手动完成两到三节课。然后决定你需要什么样的物理类布局。然后,尝试编写程序。除非你完全明白该做什么,否则不要尝试编写程序。
顺便说一下,有多少个类/文件?
编辑:为了更好地了解良好的物理类到文件布局可能是什么,我建议阅读John Lakos的Large Scale C++ Design。有点过时,因为它不包含任何有关预编译头文件的内容,但仍然有用。
答案 5 :(得分:0)
两种基本的编码风格模式是可能的:
选项2可能会导致代码膨胀,因为如果您在多个编译单元中使用该类,您可能会在最终链接中获得多个实现副本;它取决于联系人根除这一点,它可能会也可能不会这样做 - YMMV。它还允许类的用户访问实现,这在某些情况下可能是不合需要的。
两者结合使用简单的getter / setter函数内联和单独编译单元中的较大代码体是一种选择。通常如果我有一个完全由初始化列表实现的构造函数,我会将其空体包含在内。
班级cExampleClass
的示例:
<强> cExampleClass.h 强>
class cExampleClass
{
public:
cExampleClass() ;
~cExampleClass() ;
void memberfn() ;
} ;
<强> cExampleClass.cpp 强>
cExampleClass::cExampleClass()
{
// body
}
cExampleClass::~cExampleClass()
{
// body
}
void cExampleClass::memberfn()
{
// body
}
或内联:
<强> cExampleClass.h 强>
class cExampleClass
{
public:
cExampleClass()
{
// body
}
~cExampleClass()
{
// body
}
void memberfn()
{
// body
}
} ;
在这两种情况下,任何使用cExampleClass
的源文件都只包含cExampleClass.h,而cExampleClass.cpp(如果存在)则单独编译和链接。
请注意,如果类包含静态数据成员变量,则必须在单独的编译单元中实例化这些 ,以便只有一个公共实例。例如:
<强> cExampleClass.h 强>
class cExampleClass
{
public :
static int staticmember ;
} ;
<强> cExampleClass.cpp 强>
int cExampleClass::staticmember = 0xffff ;
答案 6 :(得分:0)
我建议编写一个脚本(使用您最喜欢的脚本语言)将类声明提取到自己的文件中。如果你不擅长脚本语言,你总是可以编写一个C ++程序来提取类声明。
另一种可能性是使用具有重构功能的IDE或重构应用程序。我从未使用过这些,所以我不能就他们的能力提出建议。