在命名空间中用非成员函数取代成员函数

这个就是Effective C++条款23,假如类有多个成员函数,现在需要在一个函数里调用这几个函数,那么最好不要把它定义为成员函数,而是类外的普通函数。

最常见的做法是定义一个namespace,把类和普通函数都放到里面,namespace可以跨越多个文件,但类不能。这正是C++标准库std的风格,std有数十个文件,每个声明std的部分机能,这样能 降低编译的依存性。

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
// 头文件
namespace test {

class Base
{
public:
Base();
~Base();
void setA(int a);
void setB(int b);
private:
int m_a;
double m_b;
};
// 这里声明,但不能定义函数体,否则编译不通过
void setAB(Base& obj, int a, int b);
}

// 源文件
test::Base::Base():
m_a(0),
m_b(0)
{
cout<<"base constructor"<<endl;
}

test::Base::~Base()
{
cout<<"base destructor"<<endl;
}

void test::Base::setA(int a)
{
m_a = a;
}

void test::Base::setB(int b)
{
m_b = b;
}
//必须加test:: ,否则编译不通过
void test::setAB(Base& obj, int a, int b)
{
obj.setA(a);
obj.setB(b);
}

// 调用
test::Base b;
test::setAB(b, 43, 23);

setAB函数在类Base之外,这样的封装性比作为成员函数要好,它并不增加能访问类private成员的函数数量,有较低的编译相依度。

类放到命名空间后,继承类可以像平常那样继承,不必也放到这个命名空间里。