2014-03-05 61 views
1

我一直在寻找头文件中使用使用声明的一些说明(我在四处搜索,但无法完全得到我正在寻找的答案)。我的研究结论迄今为止,在非全局范围内使用它们是可以的,而命名空间指令是不好的。我明白(至少我希望如此:))。在头文件中使用声明

所以在我的例子中我使用了shared_ptr s,但我需要支持在std::命名空间中没有它们的旧编译器,例如std::tr1::。由于每个使用shared_ptr的类都需要相同的shared_ptr定义,因此我必须在每个这些头文件中放入正确的#include指令并使用声明。所以我将这部分移到了一个单独的头文件中,所以我只有一个文件需要进行更改。关于使用哪个shared_ptr的决定是通过预处理器指令HAS_SHAREDPOINTER进行的,如果用户具有支持std::shared_ptr的编译器,则该设置被设置。

SharedPtr.h

#ifndef SHAREDPTR_H_ 
#define SHAREDPTR_H_ 

#ifdef HAS_SHAREDPOINTER 
#include <memory> 
using std::shared_ptr; 
#else 
#include <tr1/memory> 
using std::tr1::shared_ptr; 
#endif 

#endif /* SHAREDPTR_H_ */ 

现在在使用shared_ptr的每一个头文件,包括我这个头文件。例如,在

ModelPar.h

#ifndef MODELPAR_H_ 
#define MODELPAR_H_ 

#include <string> 
#include <set> 

#include "SharedPtr.h" 

class ModelPar { 
    private: 
    std::set<shared_ptr<ModelPar> > connections; 
    ... 
}; 

#endif /* MODELPAR_H_ */ 

现在我认为我所做的是错的,因为这包含任何我的头文件(使用shared_ptr S)用户的方式也有相应的在他的代码中使用声明。这是坏事,因为用户没有意识到这一点......所以我把我的使用声明放在全局范围内。要么?我有点困惑和困惑如何正确地做到这一点?提前致谢!

回答

0

好的,我自己找到了“答案”。我想我没有意识到命名空间中的using声明在名称空间相同的名称空间下仍然有效。现在Bjarne的话也更有意义,人们不应该污染全球命名空间:)。如果我仍然做错了,请纠正我。

SharedPtr.h:

#ifndef SHAREDPTR_H_ 
#define SHAREDPTR_H_ 

#ifdef HAS_SHAREDPOINTER 
#include <memory> 
namespace blub { 
using std::shared_ptr; 
} 
#else 
#include <tr1/memory> 
namespace blub { 
using std::tr1::shared_ptr; 
} 
#endif 

#endif /* SHAREDPTR_H_ */ 

ModelPar.h:

#ifndef MODELPAR_H_ 
#define MODELPAR_H_ 

#include <string> 
#include <set> 

#include "SharedPtr.h" 

namespace blub { 

    class ModelPar { 
    private: 
    std::set<shared_ptr<ModelPar> > connections; 
    ... 
    }; 
} 

#endif /* MODELPAR_H_ */ 
+0

也许是文体偏好的问题,但是......定义在namespace blub中使用条件'shared_ptr'的所有内容是没有必要的,也不太直观。并且认为在'struct's中声明类型别名是有利的(例如,用于模板),无法为定义重新打开它作为类型名称的快捷方式。所以,据我所知,更习惯的方法是使用包含它的'namespace'或'class'来限定别名的所有用法:'struct MyTypes {using shared_ptr = std :: shared_ptr; }; /*...*/ std :: set >' –

0

我本人没有看到有任何头 '使用' 任何好处。 永恒

这不仅使得它非常难以重新设置因为编译器错误将变得毫无用处,如果您删除标题头包含链。获取错过声明300多错误,未定义类型等;并不完全是我对'有趣时间'的定义。

当然,您可以使用一些预处理器魔术来完成它,而不管名称冲突。但为什么?如果你的命名空间有碰撞,那么你的方法就会出现问题,这样绕过火灾报警器并声称不再有火灾。

作为额外的好处,它也掩盖了班级的祖先“我是从X命名空间使用FooClass还是从Y?”。

+0

嗨Manuel,嗯,我明白你的意思,并且认为把它放在头文件中是没有意义的,但只是在源文件中文件。通常这就是我所做的,但是我怎么能解决这个问题呢?不幸的是,我不能要求C++ 11的项目,所以我必须适应...... – steve

+0

在你的头文件中,你需要使用你正在使用的类的完整声明。像'std :: set >连接;'。 看起来像你想要的是一个位置来管理你正在使用的实现;因为你可以用一个包装器来包装共享指针,所以使用它看起来像'std :: set >连接;' – Manuel

相关问题