C++:我应该使用“typedef”还是“使用命名空间”?[已结束]

C++: Should I use 'typedef' or 'using namespace'? [closed]

提问人:vidit 提问时间:4/26/2012 最后编辑:vidit 更新时间:2/29/2016 访问量:22221

问:

我正在编写一个具有多个依赖模块的库。当我包含来自不同模块的文件时,我是否应该使用以下命令解析命名空间:

using namespace project1::namespace1;
class1 obj;

typedef project1::namespace1::class1 class1;
class1 obj;

每种方法的优缺点是什么?我在某处读到我们应该在 .H 文件和 .C文件,这是可取的吗?typedefusing

我在使用“typedef”时遇到的一个问题是,如果我在第三个模块中同时包含原始类和带有“typedef”的类,则会导致命名空间歧义。

C++ 命名空间 using 指令

评论

18赞 hmjd 4/26/2012
另一种选择是using project1::namespace1::class1;
1赞 bmargulies 4/26/2012
“视情况而定”。这里没有一个正确的答案。
0赞 vidit 4/26/2012
@bmargulies 谢谢。你能详细说明一下吗?
0赞 bmargulies 4/26/2012
C++ 没有连贯的设计结构,因为它随着时间的推移在 C 之上逐渐添加了自己的功能。因此,它同时具有“using”和“typedef”,并且对于单个项目,它们在实用性上很难区分。
0赞 Rup 4/26/2012
“我们应该在 .H 文件和 .C 文件“ - 我不同意在 .h 文件中使用整个命名空间,因为这意味着您正在用 .c 文件可能意想不到的东西污染全局命名空间。.c 文件是它自己的编译单元,可以做任何它想做的事情。但是,我认为 hmjd 的解决方案比 typedef 更好。

答:

6赞 IProblemFactory 4/26/2012 #1

最清晰的方法是不使用这些方法中的任何一种 - 只需编写 .new project1::namespace1::class1()

评论

0赞 William Payne 3/13/2013
这也许是,但有时会有点啰嗦,不是吗?
76赞 juanchopanza 4/26/2012 #2

您陈述的两个选项并不等同。这个:

using namespace project1::namespace1;

从命名空间中提取所有内容,几乎无法控制,并且可能会发生冲突。我在这里只看到缺点,没有优点。

但是你不需要使用 a 来引入单个符号,你可以使用typedef

using project1::namespace1::class1;

无论你使用这个还是使用它,都不会有太大的区别。但请记住,这仅限于类型和枚举,而可以引用值、函数等:typedeftypedefusing

namespace X {
  const int x{42};
  enum Fruit{Apple, Pear};
}

using X::x; // OK
typedef X::x xx; // Error! 'x' in namespace 'X' does not name a type

所以这两个表达式并不完全等价。

评论

1赞 vidit 4/26/2012
听上去很好。这也将解决问题中提到的 ambuiguity 问题。
3赞 Lyn 4/26/2012 #3

using project1::namespace1::class1

或者,您可以限制在本地范围内使用 namespce,这既是为了方便起见,又不会破坏全局命名空间。

void function()
{
    using namespace project1::namespace1;

    class1 obj;

    ...
}
8赞 parkovski 4/26/2012 #4

切勿仅仅为了让名称更易于键入而在头文件中使用 OR。usingtypedef

在源文件中,由您决定。写出整个名字似乎被认为是很好的做法,因为它可以非常清楚地表达您的意思。如果命名空间太长,可以使用命名空间别名来减少混乱,但仍要保持含义清晰:namespace ns = project1::namespace1;

无论哪种方式,如果要将符号导入全局命名空间,请使用 ,而不是 。 主要用于您想用不同的名称调用类型时,很多时候是因为它是一个模板 - 例如,而不是 ,它仍然很清楚,但类型更好。usingtypedeftypedefmy_mapstd::map<std::string, my_type>

另外,请参阅以下问题:为什么“使用命名空间 std”被认为是不良做法?

评论

6赞 SigTerm 4/26/2012
永远不要在标题中使用?认真地?-1 .标准做法是类型定义要在应用的其余部分中使用的几种类型,并将它们全部放在一个标头中。例子包括 libsdl 中的 Uint8 和 Qt 4 中的 quint16。typedef
3赞 David Schmitt 4/26/2012
@SigTerm:Parkovski 不赞成在标头中缩写传入类型以供本地使用。使用 typedefs 来定义公开的 API 是完全不同的,也可以。
6赞 SigTerm 4/26/2012
@DavidSchmitt:你提到的两种“使用模式”是相同的,代表的是同一件事——你制作中央标头并使用该标头中声明的类型。是否用于“导入”/“导出”无关紧要。Parkovski 的建议听起来很不合理,因为 *.h 中有很多地方可以放置 typedef——你可以将它包含在 class、namespace 等中,这是安全的。此外,typedef 不会造成混乱。因此,无论你怎么看,“*.h 中没有 typedef”听起来像是对编码风格的毫无意义的人为限制——没有任何好处,所以不应该使用这个规则。
0赞 parkovski 4/28/2012
@SigTerm 我不认为你读过这句话的其余部分。标准 C 在标头中有大量非常有用的 typedef(例如)。不同之处在于这些是 API 的一部分,用于特定目的,而不仅仅是“因为我不喜欢 2 类型”的人的快捷方式。size_tptrdiff_t