我对C ++中标题和实现文件之间的关系有疑问。
我收到了两个空头文件和一个空实现文件。当我说“空”时,我的意思是文件只包含方法声明;我必须在每个方法中实现代码。 (我认为发布这三个文件的代码是多余的,因为它们只包含声明..)
这三个文件是:
interface_complexmutex.h
complexmutex.h
complexmutex.cpp
interface_complexmutex.h
为complexmutex
提供了虚拟方法。此外,complexmutex
类继承自interface_complexmutex
。
这些文件具有我必须实现的基本互斥函数。我有两个问题:
为什么我需要interface_complexmutex.h
?它实际上没有.cpp
文件,整个实现都在complexmutex
个文件中,对吗?
我应该如何包含这些文件并在程序中使用complexmutex
类? (例如,如果我在init()
中使用complexmutex.cpp
方法)
main.cpp
应该是这样的吗?
#include <stdlib.h>
#include <stdio.h>
#include "interface_complexmutex.h"
#include "complexmutex.h"
using namespace std;
int main(){
complexmutex a;
/* do something with mutex to test */
return 0;
}
我制作了自己的Makefile,到目前为止上面的代码运行正常。
答案 0 :(得分:2)
1)只有在以后可能会改变实施时,才需要接口。这将使您可以自由地对代码的内部进行所需的所有更改,而不会影响使用它来创建软件的人员。这意味着用户应仅查看接口类,从不实现。
为此,您需要实现所谓的factory
模式。这是一个函数,它将创建实现类的实例并将其作为指针(或引用)返回给接口类。您可能可以将该函数编写为接口类的静态方法。
2)在程序中,您应该想象您是代码的用户。用户不关心如何实现您的功能,因此根本不应该使用该实现。如果可能,它应该只包括接口头并调用工厂方法,如下所示:
#include "interface_complexmutex.h"
using namespace std;
int main(...) {
interface_complemutex* mutex = interface_complexmutex::create_new(...);
// do something interesting with the mutex
}
在此示例中,create_new
是您的工厂方法。如果你有不同的实现,你可以有它的参数(通常是枚举)。
使用接口(实际上是C ++中的抽象类)时,需要使用指针或引用。您无法为抽象类创建值。当然,如果您编写测试代码,它会有所不同,因为测试代码不会被您的库用户看到/使用。
注意:
我要指出,命名非常糟糕。接口应该命名为complexmutex
和实现complexmutex_impl
,因为用户应该更多地使用接口,它的名称应该更短(并且你可以用相关的东西替换“impl”,如“pthread”,如果你使用pthreads来实现你的互斥类。
作为PS注释,在C ++ 0x中有一个包含互斥锁的线程库。它已经得到了一些编译器的支持。
答案 1 :(得分:1)
接口类(包含所有虚函数的C ++类)有助于重用接口设计。理想情况下,这些类只捕获接口而不是实现。因此,它们只有.h文件而不是相应的.cpp文件。
开始重用,假设我们需要定义另一个互斥类,实现完全不同。我们将无法重用complexmutex类实现,但仍能够重用interface_complexmutex类。另外,可以使用新互斥类的对象代替complexmutex,因为它们具有通用接口。