大佬教程收集整理的这篇文章主要介绍了如何克服C头文件的命名空间邪恶?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
到目前为止,我对命名空间完全没问题,但是当涉及到头文件时
在完全合格的课程方面,事情变得低效
名称,使用指令和使用声明.
关于这个问题的一个很好的描述是Herb Sutter的this文章.
据我所知,这一切归结为:如果你总是写一个头文件
使用完全限定类型名称来引用其他名称空间中的类型.
这几乎是不可接受的.由于C头通常提供声明
在一个类中,最大可读性具有最高优先级.完全符合条件
最后,来自不同命名空间的类型会产生很多视觉噪音
将标题的可读性降低到提出问题的程度
是否要使用名称空间.
不过我想利用C命名空间,所以考虑一下
问题:如何克服C头文件的命名空间邪恶?后
一些研究我认为typedef可能是解决这个问题的有效方法.
下面你将找到一个C示例程序,它演示了我的意思
喜欢使用公共类作用域typedef从其他名称空间导入类型.
该程序在语法上是正确的,并在MinGW W64上编译良好.到目前为止
很好,但我不确定这种方法是否会愉快地删除using关键字
从标题但引入另一个我根本不知道的问题.
就像Herb Sutter描述的东西一样棘手.
那是我恳请所有对C有透彻了解的人
检查下面的代码,让我知道这是否有效.谢谢
为了你的想法.
#ifndef MYFIRSTCLASS_HPP_ #define MYFIRSTCLASS_HPP_ namespace com { namespace company { namespace package1 { class MyFirstClass { public: MyFirstClass(); ~MyFirstClass(); private: }; } // namespace package1 } // namespace company } // namespace com #endif /* MYFIRSTCLASS_HPP_ */@H_723_4@myFirstClass.cpp
#include "MyFirstClass.hpp" using com::company::package1::MyFirstClass; MyFirstClass::MyFirstClass() { } MyFirstClass::~MyFirstClass() { }@H_723_4@mySecondClass.hpp
#ifndef MYSECONDCLASS_HPP_ #define MYSECONDCLASS_HPP_ #include <@R_489_10495@ng> #include "MyFirstClass.hpp" namespace com { namespace company { namespace package2 { /* * Do not write using-declarations in header files according to * Herb Sutter's Namespace Rule #2. * * using std::string; // bad * using com::company::package1::MyFirstClass; // bad */ class MySecondClass{ public: /* * Public class-scoped typedefs instead of using-declarations in * namespace package2. Consequently we can avoid fully qualified * type names in the remainder of the class declaration. This * yields maximum readability and shows cleanly the types imported * from other namespaces. */ typedef std::string @R_489_10495@ng; typedef com::company::package1::MyFirstClass MyFirstClass; MySecondClass(); ~MySecondClass(); @R_489_10495@ng getText() const; // no std::string required void setText(@R_489_10495@ng as_text); // no std::string required void setMyFirsTinstance(MyFirstClass anv_instancE); // no com::company:: ... MyFirstClass getMyFirsTinstance() const; // no com::company:: ... private: @R_489_10495@ng is_text; // no std::string required MyFirstClass inv_myFirsTinstance; // no com::company:: ... }; } // namespace package2 } // namespace company } // namespace com #endif /* MYSECONDCLASS_HPP_ */@H_723_4@mySecondClass.cpp
#include "MySecondClass.hpp" /* * According to Herb Sutter's "A Good Long-Term Solution" it is fine * to write using declarations in a translation unit,as long as they * appear after all #includes. */ using com::company::package2::MySecondClass; // OK because in cpp file and // no more #includes following MySecondClass::MySecondClass() { } MySecondClass::~MySecondClass() { } /* * As we have already imported all types through the class scoped typedefs * in our header file,we are Now able to simply reuse the typedef types * in the translation unit as well. This pattern shortens all type names * down to a maximum of "ClassName::TypedefTypename" in the translation unit - * e.g. below we can simply write "MySecondClass::string". At the same time the * class declaration in the header file Now governs all type imports from other * namespaces which again enforces the DRY - Don't Repeat Yourself - principle. */ // Simply reuse typedefs from MySecondClass MySecondClass::string MySecondClass::getText() const { return this->is_text; } // Simply reuse typedefs from MySecondClass void MySecondClass::setText(@R_489_10495@ng as_text) { this->is_text = as_text; } // Simply reuse typedefs from MySecondClass void MySecondClass::setMyFirsTinstance(MyFirstClass anv_instancE) { this->inv_myFirsTinstance = anv_instance; } // Simply reuse typedefs from MySecondClass MySecondClass::MyFirstClass MySecondClass::getMyFirsTinstance() const { return this->inv_myFirsTinstance; }@H_723_4@main.cpp的
#include <cstdio> #include "MySecondClass.hpp" using com::company::package2::MySecondClass; // OK because in cpp file and // no more #includes following int main() { // Again MySecondClass provides all types which are imported from // other namespaces and are part of its interface through public // class scoped typedefs MySecondClass *lpnv_mySecCls = new MySecondClass(); // Again simply reuse typedefs from MySecondClass MySecondClass::string ls_text = "Hello World!"; MySecondClass::MyFirstClass *lpnv_myFirClsf = new MySecondClass::MyFirstClass(); lpnv_mySecCls->setMyFirsTinstance(*lpnv_myFirClsf); lpnv_mySecCls->setText(ls_text); printf("GreeTings: %s\n",lpnv_mySecCls->getText().c_str()); lpnv_mySecCls->setText("Goodbye World!"); printf("GreeTings: %s\n",lpnv_mySecCls->getText().c_str()); getchar(); delete lpnv_myFirClsf; delete lpnv_mySecCls; return 0; }
一些提示:
>删除“com”命名空间级别. (这只是一个你不需要的java-ism)
>删除“company”命名空间,可以替换为“product”或“library”命名空间(即boost,Qt,OSG等).只需挑选一些独特的东西w.r.t.您正在使用的其他库.
>您不需要完全声明您所在的名称空间中的名称(请注意:模板分类,请参阅注释).只需避免在标头中使用任何名称空间指令. (并且在C文件中小心使用,如果有的话.首选内部函数.)
>考虑命名空间别名(在functions / cpp文件中),即namespace bll = boost :: lambda;.这会创建非常简洁的快捷方式.
>此外,通过使用pimpl模式隐藏私有成员/类型,您的标头显示的类型较少.
以上是大佬教程为你收集整理的如何克服C头文件的命名空间邪恶?全部内容,希望文章能够帮你解决如何克服C头文件的命名空间邪恶?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。