2012-02-06 78 views
5

我已经在外部* .cpp文件中定义了一些函数(这里没有涉及类),当然还有一个合适的* .h文件。收到我在实现文件中使用未命名的名称空间?

* .cpp文件中的某些功能仅在中使用,在* .cpp文件中无处可用。他们甚至没有在* .h文件中提及。

我应该将这些函数放到一个未命名的命名空间中吗?或者他们可能住在旁边的其他函数?如果是这样,为什么我需要一个未命名的名称空间给他们?我看不出问题,因为无论如何这些功能都无法从外部访问。

+0

为什么不让它们变成静态的? (如在一个静态的C函数,而不是一个静态类方法) – 2012-02-06 17:41:40

+1

@JamesMcLaughlin:在C + + 03“静态”已被弃用,为此目的。但是,C++ 11并不反对它。但是'静态'并且处于未命名的名称空间中意味着不同的事情。 'static'会给它内部的连接,所以这个函数不能用于某些目的。 – 2012-02-06 17:45:18

+0

感谢您的建议。 这些解决方案是静态的还是无名的命名空间,推荐或首选? – user1192880 2012-02-06 17:49:02

回答

9

如果您希望它们对该编译单元真正是私有的,请将它们置于匿名命名空间中。如果你不这样做,那么有人可以在别处声明这些功能并明确地使用它们。

看看下面的例子:

// library.cpp 

// a "private" function here, in that it is not declared anywhere 
void f() {} 

namespace 
{ 
    // same as above, except within an anonymous namespace 
    void g() {} 
} 

// client.cpp 

void f(); 

int main() 
{ 
    // Can call f(), it's been declared and is now effectively "public" 
    f(); 

    // compilation error, this has no idea what g() is, it's not declared 
    // in any scope that can be resolved here 
    g(); 

    return 0; 
} 
+0

谢谢!我不知道那个“功能”。 – user1192880 2012-02-06 17:50:06

+0

这就是'static'的用途。匿名命名空间为类和结构体提供了此功能。 – 2012-02-06 18:01:01

+0

'static'关键字是否也可以防止与代码其他部分中可能存在的其他函数发生名称冲突?未命名的命名空间将会。 – Chad 2012-02-06 19:09:32

1

我想如果你不想被从外面看到这些函数声明为static

+0

*“...从外面看......” - - 从什么外面?标题?翻译单位? – jww 2017-09-29 07:15:26

4

你的问题可以被一分为二:

1“?如何隐藏全局函数”

一个简单的方法来做到这一点,是把函数的头到头文件:

//============================ 
// Filename: "mylibrary.hpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
#ifndef MYLIBRARY_H_INCLUDED 
#define MYLIBRARY_H_INCLUDED 
//============================ 

namespace MyLibrary 
{ 
    void DoSomething(); 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

全部代码文件:

//============================ 
// Filename: "mylibrary.cpp" 
//============================ 
// Description: 
// Utility functions. 
//============================ 
// self header include 
#include "mylibrary.hpp" 
//============================ 

namespace MyLibrary 
{ 
    void DoSomethingBefore() 
    { 
     // ... 
    } 

    void DoSomethingAfter() 
    { 
     // ... 
    } 

    void DoSomethingConfirmed() 
    { 
     // ... 
    } 

    void DoSomething() 
    { 
     DoSomethingBefore(); 
     DoSomethingConfirmed(); 
     DoSomethingAfter(); 
    } 
} // namespace MyLibrary 

//============================ 
#endif // MYLIBRARY_H_INCLUDED 
//============================ 

当这编译,你会得到一个“mylibrary.o”或“mylibrary.obj”文件。您可以将其提供给其他开发人员:“mylibrary.hpp”加上“mylibrary.obj”,但不带“mylibrary.cpp”文件。大多数“普通c”/“C++”编译器都可以这样工作。

还有其他的方法,请阅读下一节。

2.“匿名命名空间是隐藏全局函数的好技术吗?”

“匿名命名空间”技术是隐藏全局函数的另一种方法。

有一个类似的问题:

Unnamed/anonymous namespaces vs. static functions

但是,我个人不推荐这种技术,被誉为“最喜欢”的答案。

命名空间是其中之一,我希望自“纯c”或“C++”开始就存在。但是,“匿名命名空间”或“无名命名空间”似乎很奇怪。

它就像试图隐藏一些东西,然后忘记,你在哪里存储它。

3项其他建议

(一)我建议使用单一主REQUIRED,每个文件不可选,非匿名的命名空间。它可能具有嵌套的附加内部命名空间。每个主名称空间应该具有相同的ID。作为文件名,但没有文件扩展名或文件后缀。 (b)避免匿名命名空间。它像存储仓库中的东西,没有索引。 (c)在头文件中使用文件扩展名或文件前缀,可能是“.h”或“.hpp”,即使它是一个C++文件也是如此。该标准规定C++不应在“C++”文件上使用文件扩展名或文件后缀,但很难在文件系统上识别或查找。

祝你好运。

相关问题