我遇到multiple defintion of Math
错误而没有来自以下代码的原因文件:
#ifndef SOMEMATH_H
#define SOMEMATH_H
class math{
public:
int add( int a, int b);
int divide(int a, int b);
int subtract(int a, int b);
int multiply( int a, int b);
}Math;
#endif // SOMEMATH_H
将Math
更改为任何其他名称不会改变问题。以不同方式实例化数学对象不能解决问题。不在头文件中创建math
的对象不会导致任何问题,但我想在标头中创建一个类。这可能吗?
答案 0 :(得分:2)
简短回答:标题中没有实例化。
答案很长:您的文件直接或间接包含在其中的每个cpp都有一个对象Math
,链接器会抱怨,因为它不能只选择一个。
关于这个主题的更多内容,http://csapp.cs.cmu.edu/public/ch7-preview.pdf涵盖了unix链接器,但这个想法将保持不变。基本上你的例子失败了:
规则1:不允许使用多个强符号
说实话,我认为(但不确定)在大多数情况下,链接器可以决定在大多数情况下创建对符号的引用,并将“.o”中的一个作为真实内容宾语。但只有1个库,因此一旦你有多个DLL,bug就会上升。所以这不值得痛苦。
所以一般规则是“头部没有实例化”。如果你想要一个全局变量:
math Math
(如果需要,甚至是专用的)。但如果可以,请避免使用全局对象。
答案 1 :(得分:2)
您的标头定义了class math
名为Math
的实例,这是一个坏主意,因为它会导致您遇到的问题:如果两个文件包含标题,则会获得两个实例一样的名字。
您无法在此标头中安全地创建类的实例。您可以声明存在的那个,并将实际的定义放在.cpp
源文件中。
这个特殊的类看起来只有方法,没有与之关联的实际数据。这让我想知道你真正想要做什么。如果您只是在一个名称下捆绑一组函数,则可以考虑使用namespace
,或者至少在类下面设置函数static
:
class Math {
public:
static int add( int a, int b);
static int divide(int a, int b);
static int subtract(int a, int b);
static int multiply( int a, int b);
};
或:
namespace Math
{
int add( int a, int b);
int divide(int a, int b);
int subtract(int a, int b);
int multiply( int a, int b);
}
这些选项中的任何一个都将使您无需使用类的实例来访问该功能。您可以将这些功能称为Math::add()
,Math::divide()
等
答案 2 :(得分:1)
// .hpp
#ifndef SOMEMATH_H
#define SOMEMATH_H
class math{
public:
int add( int a, int b);
int divide(int a, int b);
int subtract(int a, int b);
int multiply( int a, int b);
};
extern math Math;
#endif // SOMEMATH_H
// .cpp
math Math;
但看起来你正试图模仿Java的Math类。只需使用命名空间。