5

我目前正在尝试以更好的方式组织我的代码。

为此,我使用了命名空间,按组件对类进行分组,每个组件都有定义的角色和一些接口(实际上是抽象类)。

我发现它非常好,尤其是当我必须重写整个组件并且我这样做几乎没有对其他组件产生影响时。(我相信使用一堆混合的类和方法会困难得多)

然而,我对它并不是 100% 满意。特别是我想更好地分离接口、组件的公共面以及它们背后的实现。我认为组件本身的“接口”应该更清晰,我的意思是新手应该很容易理解他必须实现哪些接口,他可以使用哪些接口以及实现的一部分。

很快我将开始一个涉及多达 5 名开发人员的更大项目,我想清楚这一点。

那你呢?你怎么做呢?你如何组织你的代码?

4

5 回答 5

4

有两种常见的方法:

如果除了公共接口之外,您只需要一些辅助函数,只需将它们放在实现文件中的未命名命名空间中即可:

// header:

class MyClass {
// interface etc.
};

// source file:

namespace {
    void someHelper() {}
}

// ... MyClass implementation

如果您发现自己想要隐藏成员函数,请考虑使用 PIMPL 习惯用法:

class MyClassImpl; // forward declaration

class MyClass {
public:
    // public interface
private:
    MyClassImpl* pimpl;
}; 

MyClassImpl实现功能,同时MyClass将对公共接口的调用转发给私有实现。

于 2010-01-21T19:46:04.587 回答
4

特别是我想更好地分离接口、组件的公共面以及它们背后的实现。

我认为您正在寻找的是外观模式:

外观是一个对象,它为更大的代码体(例如类库)提供简化的接口。——维基百科

如果您的类中有复杂的交互,您可能还想查看MediatorBuilder模式。

Pimpl idiom(又名编译器防火墙)对于隐藏实现细节和减少构建时间也很有用。当我不需要多态性时,我更喜欢在接口类 + 工厂上使用 Pimpl。但请注意不要过度使用它。不要将 Pimpl 用于通常分配在堆栈上的轻量类型(如 3D 点或复数)。将它用于更大、寿命更长的类,这些类依赖于您希望对用户隐藏的其他类/库。

在大型项目中,当使用简单的前向声明时,不要在头文件中使用#include 指令,这一点很重要。仅在绝对必要时将#include 指令放在头文件中(最好将#includes 放在实现文件中)。如果操作正确,正确的#include 规则将显着减少编译时间。Pimpl 习惯用法可以帮助将#includes 从头文件移动到相应的实现文件。

一个连贯的类/函数集合可以在它自己的命名空间中组合在一起,并放在源代码树的子目录中(子目录应该与库命名空间同名)。然后,您可以为该包创建一个静态库子项目/makefile,并将其与您的主应用程序链接。这就是我认为 UML 术语中的“包”。在一个理想的包中,类之间是紧密相关的,但与包外的类的关系却是松散的。绘制包的依赖关系图有助于确保没有循环依赖关系。

于 2010-01-22T00:01:00.527 回答
1

您可能会发现大型 C++ 软件设计中的一些建议很有用。它有点过时(1996 年出版)但仍然很有价值,它提供了结构化代码的指针,以最大限度地减少“单个头文件更改时重新编译世界”的问题。

于 2010-01-21T20:57:10.033 回答
0

Herb Sutter 关于“类中有什么?- 接口原则”的文章提出了一些在设计接口时似乎没有想到的想法。它有点过时了(1998 年),但里面还是有一些有用的东西。

于 2010-01-21T21:46:31.787 回答
-6

首先声明你的变量,你可以在一个字符串声明中使用它们,也像这样。

 char Name[100],Name2[100],Name3[100];
 using namespace std;
int main(){

 }

如果你有一段很长的代码可以在程序之外使用,那就把它变成一个新函数。喜欢这样。

void Return(char Word[100]){
cout<<Word; 
cin.ignore();    
} 
int main(){ 
Return("Hello");
} 

我建议您将任何外部函数和声明放入头文件并像 Dev-C++ #include "Resource.h" 一样链接它

于 2010-01-21T21:20:05.700 回答