我正在从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 ++开发人员陷入困境。
答案 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()的版本,如果你包含的文件中有多个版本的话。
关于您所做的示例:如果您在声明之后立即放置定义,则不再需要声明(该定义也可以作为声明)。如果在头文件和源文件中拆分声明和定义,则仍需要原型。顺便说一下,这是推荐的,因为谁使用你的代码只需要包含标题(告诉编译器“应该如何调用你的函数”)。在链接时只需要定义。
希望我至少解决了一下你的问题...; - )