C++ 接口与实现

封装是 C++ 面向对象三大特性之一。C++ 通过将数据和对数据操作的函数绑定在一个类里来表达封装。从字面意义和 C++ 的历史(C with class)来看,封装对于 C++ 来说是根本的。

《代码大全2》6.2节 中提到了一个良好的封装应该“避免把私有的实现细节放入类的接口中”,并介绍了 《Effective C++》 中提到的 pImpl 惯用技法。

在我看来 C++ 中类的实现方式明显无法很好的表达封装,只是粗暴的将函数及其操作的数据绑在一起,而忽视了可见性的控制。C++ 对运行时性能苛求可能是其罪魁祸首。

实际上我认为封装从根本上就是一个错误的观点,数据和对数据操作的函数从来就不是一个整体。

好吧,本文要说只是另一种定义 C++ 类的方式,类似 Objective-C 类的 interface/implementation 。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// foo_interface.hpp
#include <boost/noncopyable.hpp>

namespace foo {

class Interface : boost::noncopyable {
public:
int Bar();
};

}

// foo.hpp
#include "foo_interface.hpp"

#include <boost/shared_ptr.hpp>

namespace foo {

typedef boost::shared_ptr<Interface> Reference;

Reference New();

}

// foo.cpp
#include "foo.hpp"

namespace foo {

class implementation : public Interface {
public:
int Bar() {
// ...
return bar0();
}

implementation() {
// ...
}

private:
int priv_data0;
// ...

int bar0() {
// ...
}

};

int Interface::Bar() {
BOOST_AUTO(impl, static_cast<implementation>(this));
return impl->Bar();
}

Reference New() {
return Reference(new implementation());
}

}

foo::Interface 中只包含 foo 对外提供的接口函数,没有数据成员。