命名空间是否在C ++中呈现原型方法已过时?

时间:2012-01-20 20:06:13

标签: c++ namespaces prototype

我正在从C迁移到C ++,我注意到的第一件事就是命名空间内的原型设计冗余。我正在尝试利用命名空间的功能来清楚地标记我的添加/修改。

namespace ns {
    void sayHello (void);   //<-- NOT REQUIRED, BUT IS THERE ANY PURPOSE?
    void sayHello (void) {
        std::cout << "Hello world!";
        return;
    }
}

int main(int argc, char *argv[]) {
    ns::sayHello();
}

以前,在C中,使用原型是一个很好的措施,因此您不需要在源代码中的main()上面编写函数。在我看来,名称空间必须在使用前定义,因此,任何嵌套函数也会在使用前编写。

我刚刚开始使用C ++,我想开始正确。我一直在互联网上阅读几个教程,但他们并没有真正提到这个主题。我知道这很“简单”,但请饶恕我的投票和翻阅评论。如果有人能够做到,我将不胜感激地深入讨论这是否过时,和/或这种情况最终可能会让新的C ++开发人员陷入困境。

4 个答案:

答案 0 :(得分:5)

不一定。声明和定义仍然是不同的概念。另请注意,命名空间可以跨越多个文件,并且定义不需要在命名空间中。

//test.h
namespace test
{
   void foo();
   //no implementation in header
}

//main.cpp
int main()
{
   test::foo();
   return 0;
}

//test.cpp
namespace test
{
   void foo() { };
   //definition here
   //without the definition, we'd get a link error
}

C ++中的实现分离是出于诸如保密代码,加快编译速度(更改标题中的定义需要重新编译所有包含文件),隐藏实现细节或更清晰的结构等原因。

答案 1 :(得分:0)

如果拆分标题和实现文件,则需要原型。

答案 2 :(得分:0)

您将声明放在头文件中,将定义放在源文件中,例如

例如ns.h:

namespace ns {
    void sayHello (void);
}

在ns.cc中:

namespace ns {
    void sayHello (void) {
        std::cout << "Hello world!";
        return;
    }
}

在main.cc中:

#include "ns.h"

int main(int argc, char *argv[]) {
    ns::sayHello();
}

答案 3 :(得分:0)

我不确定我是否理解你的问题。也就是说,命名空间并没有改变函数的声明/定义过程。命名空间的目的只是为了让编译器能够理解你所调用的foo()的版本,如果你包含的文件中有多个版本的话。

关于您所做的示例:如果您在声明之后立即放置定义,则不再需要声明(该定义也可以作为声明)。如果在头文件和源文件中拆分声明和定义,则仍需要原型。顺便说一下,这是推荐的,因为谁使用你的代码只需要包含标题(告诉编译器“应该如何调用你的函数”)。在链接时只需要定义。

希望我至少解决了一下你的问题...; - )