类在编译时互相干扰

时间:2012-02-12 18:11:01

标签: c++ class namespaces

我正在开发一个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中定义

我疯了。我不知道为什么会这样,或者如何解决它。我真的很感激,如果有人可以帮助我,请,任何额外的建议都会很棒,因为我真的想尽可能多地学习这个项目。谢谢!

3 个答案:

答案 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,并在实现文件中为其提供定义。