类在编译时相互干扰

Classes interfering with each other on compile

本文关键字:干扰 编译      更新时间:2023-10-16

我正在做一个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

这个文件包括一个现在什么都不做的主函数,如果没有主函数,我就无法编译整个项目。。。

我有一个高斯。h,我没有包括任何东西,这是错的吗?

第三个类没有属性,只有方法(再说一遍,这是错的吗?还是不漂亮?)。truncatedFunctions.cpp

#include "specificMath.h"
#include <stdlib.h>
#include "truncatedFunctions.h"
#include "gaussian.h"
using namespace specificMath;

还有它的截断函数.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 中首次定义的

我快疯了。我不知道为什么会发生这种情况,也不知道如何解决它。如果有人能帮我,我将不胜感激,请提供任何额外的建议都会很好,因为我真的在努力通过这个项目学到尽可能多的东西。谢谢

当我"制作"它时,它似乎编译得很好,但当它到达链接部分时,我会收到很多错误,说我的margin.cpp类上的东西是在truncatedFunctions.cpp 中首次定义的

您是否在特定Math.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

当您包含coolstup.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"。这取决于你。

很难判断您的代码中是否做错了什么(因为您没有显示任何错误),但首先要尝试的是"清理"您的构建并重新生成所有代码。如果编译器(不知道你在用什么)出于某种原因没有编译所有修改过的模块,那么链接器出现问题也就不足为奇了。

我的第一个问题是,对于c++命名空间,合适的文件扩展名是什么?

在C++中,头文件通常是.h.hpp。这对编译器来说并不重要。

#include "gaussian.h"
#include "specificMath.h"
#include <iostream>

一般来说,最好先从标准库中提取#include内容,然后再提取自己的内容。

我有一个高斯。h,我没有包括任何东西,这是错的吗?

没有。如果你不需要包含任何内容,就不要包含任何内容。

首先,对标头使用include保护。

#ifndef MYHEADER_H
#define MYHEADER_H
//header contents
#endif

这将防止同一标头在同一翻译单元中被包含两次。

第二,不要在标题中定义未加密的内容:

double x = 0;

这将导致所有翻译单元导出该符号。

在头中声明变量extern,并在实现文件中为其提供定义。