C++的封装(七):namespace

C++很多类型在定义的时候,同时也定义了一些标志,供用户调用的时候使用。典型的,如STL的iostream,打开文件时,就需要用到一些预定义的标志。

#include 
using namespace std;

int main()
{
	ofstream fp("test.txt", ios::out|ios::app|ios::ate);
}

这样,既显得臃肿记忆又有些负担:用到的out,ate,app标志究竟属于ios? ios_base? basic_ios? 还是别的某个类? 用的时候需要费点脑子想一想。

这时可以把所用到名字输出到自定义的namespace中, 如:

#include 
class X {
public:
	enum {Zero, One, Two};
};

namespace ns {
	enum {Zero=X::Zero, 
		One =X::One,
		Two = X::Two
	};
}

using namespace ns;

int main()
{
	printf("%d\n", One);
}

这样使用时就不需要带上讨厌的类名作前缀了。

不幸的是,对于fstream的这个例子,仅仅这样做还是不够。这是因为在iostream库中,对_Ios_Openmode这个枚举类型重载了位运算符,而fstream中的open()函数flag也强调为_Ios_Openmode而不是普通的int类型。这就需要一点额外的技巧:

#include 
#include 
using namespace std;

namespace ns{
        enum open_flag {
        out = ios::out,
        ate = ios::ate,
        app = ios::app
        };
        typeof(ios::out) openflag=ios::out^ios::out;

        inline typeof(openflag) operator|(typeof(openflag)f, int tail)
        { return f|(typeof(openflag))tail; }
}

using namespace ns;
int main()
{
        ofstream fp("test.txt", openflag|out|ate|app);
}

这样就不再需要带上类分辨符了。是的,C++提供了足够的机制,所以没有必要强迫自己做任何事情。

你可能感兴趣的:(c++,ios,namespace)