我正在开发一个C ++项目。
我有一个具有其功能的类,然后我意识到其中一些函数与该类无关,但只是数学函数,因此我决定将它们移动到命名空间。
我的第一个问题是,c ++命名空间的适当文件扩展名是什么?
我有一个constants.h文件,我计划保存全局常量,例如PI。
现在:
#include <math.h>
const double PI = M_PI;
我之前讨论过的命名空间,现在称为:specificMath.h
#include <stdlib.h>
#include "constants.h"
... more code
我有一个gaussian.cpp:
#include "gaussian.h"
#include "specificMath.h"
#include <iostream>
... more code
这个文件包含一个现在什么都不做的主函数,我只是无法在没有主程序的情况下编译整个项目......
我有一个gaussian.h,我没有包含任何东西,这是错的吗?
第三类,它没有属性,只有方法(再次,这是错误的?还是不错?)。 truncatedFunctions.cpp
#include "specificMath.h"
#include <stdlib.h>
#include "truncatedFunctions.h"
#include "gaussian.h"
using namespace specificMath;
它的truncatedFunctions.h再次,我没有包括任何东西。
我加入的第四节课
#include "margin.h" //Its header, where I'm not including anything
#include "gaussian.h"
#include "specificMath.h"
using namespace specificMath;
当我“制作”它时,似乎编译得很好,但当它到达链接部分时,我得到很多错误,说我的margin.cpp类上的东西首先在truncatedFunctions.cpp中定义
我疯了。我不知道为什么会这样,或者如何解决它。我真的很感激,如果有人可以帮助我,请,任何额外的建议都会很棒,因为我真的想尽可能多地学习这个项目。谢谢!
答案 0 :(得分:1)
很难判断你的代码中是否有任何错误(因为你没有显示任何内容),但首先要尝试的是&#34;清理& #34;您的构建和重建所有您的代码。如果编译器(由于某种原因不知道你正在使用什么)没有编译所有修改过的模块,那么链接器出现问题并不奇怪。
我的第一个问题是,c ++命名空间的适当文件扩展名是什么?
在C ++中,头文件通常是.h
或.hpp
。这对编译器来说并不重要。
#include "gaussian.h" #include "specificMath.h" #include <iostream>
一般来说,从标准库首先开始,#include
的东西是个好主意,然后是你自己的东西。
我有一个gaussian.h,我不包括任何内容,那是错的吗?
没有。如果您不需要包含任何内容,请不要包含任何内容。
答案 1 :(得分:1)
当我“制作”它时,似乎编译得很好,但当它到达链接部分时,我得到很多错误,说我的margin.cpp类上的东西首先在truncatedFunctions.cpp中定义
您是否在您的specificMath.h中定义您的函数?您只应声明这些功能。
例如,如果您的specificMath.h包含函数定义,如
#ifndef COOL_STUFF_NSPC
#define COOL_STUFF_NSPC
#include <iostream>
namespace coolstuff{
void print(void){std::cout << "I'm declared in a header file." << std::endl;
}
#endif
并且您正在使用将此文件包含在其他几个文件中,链接器会变得疯狂。 包含表示复制。所以你已经多次定义了自己coolstuff::print
。更好的方法(以及在许多文件中使用自编写函数的唯一可能方法)是将代码拆分为标头和实现,就像在高斯中一样。
// coolstuff.namepace.h
#ifndef COOL_STUFF_NSPC
#define COOL_STUFF_NSPC
namespace coolstuff{
void print(void);
}
#endif
当你包含coolstuff.namespace.h时,它只会声明函数。你可以多次声明相同的功能。
// coolstuff.namespace.cpp
#include <iostream>
#include "cs.h"
void coolstuff::print(void){
std::cout << "Hello world!" << std::endl;
}
.cpp文件包含函数的实现。现在你的链接器不会生气,因为coolstuff::print
只有一个实现,而不是n(其中n是你使用的#include "cs.namespace.h"
的数量)。
我的第一个问题是,c ++命名空间的适当文件扩展名是什么?
没有标准的命名空间扩展名。使用.h / .cpp作为标头/实现和自定义前缀,例如'nmspc'或'nsc'。这取决于你。
答案 2 :(得分:0)
首先,使用包含保护标题。
#ifndef MYHEADER_H
#define MYHEADER_H
//header contents
#endif
这样可以防止同一个标题在同一个翻译单元中被包含两次。
其次,不要在标题中定义不合适的东西:
double x = 0;
这将导致所有翻译单元导出该符号。
在标头中声明变量extern
,并在实现文件中为其提供定义。