2013-12-19 137 views
3

内的头部声明函数指针我有一个包含以下一个简单包头:一个命名空间

// system.h 
#pragma once 
namespace System 
{ 
    void Initialize(void); 
    int (*Main)(int& argc, char** argv); 
    void Shutdown(void); 
} 

在“system.cpp”,初始化()被限定为使得所述函数指针主(INT, char **)被设置为另一个主函数,由预处理器确定将定义的任何系统将被编译(Windows,现在)。

在程序的main.cpp中,它调用上述三种功能...

所以,当这编译,我得到一个链接错误(system.cpp)抱怨系统:主(INT, char **)已经在main.cpp中定义。这是怎么回事?

// system.cpp 
#include "..\system.h" 
#ifdef _WINDOWS 
#include "windows.h" 
#else 
#define SYSTEM_UNKNOWN 1 
#endif 
void System::Initialize(void) 
{ 
#ifdef WINDOWS 
    System::Main = &Windows::Main; 
#else if SYSTEM_UNKNOWN 
    System::Main = NULL; 
#endif 
} 

void System::Shutdown(void) 
{ 
    System::Main = NULL; 
} 

我加入了 '的extern' 关键字的头......而仍然没有去。

+0

试过'extern'...不行:/我得到未解决的外部符号错误......这很奇怪。由于它是在system.cpp中定义的! – user3120381

+0

好的!显然我没有初始化函数中的定义......这是不愉快的。 – user3120381

回答

3

int (*Main)(int& argc, char** argv); 

是变量Main定义。对于声明,则需要extern

extern int (*Main)(int& argc, char** argv); 

,并在实现文件移动的定义。

你可以尝试同样的(具有相同效果),用简单的例子:

int x; 

这也是一个定义。

+0

啊,C的喜悦:你可以在这里说'extern int private_variable;'并在别人的'.c'文件中修改全局变量。 –

+0

@Joker_vD'static'关键字? –

+0

@Joker_vD:如果这个'private_variable'是通过外部链接声明的,那么它并不是真正的私有的。但事实确实如此,C的黑白联动隐私模式相当粗糙:它可以是内部的(任何人都可以访问),也可以是外部的(任何人都无法访问)。 – AnT

2

您上面的Main不只是一个声明。这也是一个定义。如果您将此标头包含在多个文件中,则每个文件都将定义一个版本Main。你想声明变量为extern后来在一个.cpp文件中定义它:

namespace System { 
    extern int (*Main)(int&, char**); // declaration 
} 

int (*Main)(int&, char**) = ...; // definition 
0

线int (*Main)(int& argc, char** argv);不应该读你读功能向前声明的方式,就像其他两个线代码框。这一行定义了一个名为Main的数据变量,它具有类型“指向函数返回int指针的指针”。它类似于在头文件中表示int j;

正如其他人所说,在它前面加extern,然后有行,因为它现在处于cpp文件,将解决你的问题。不过,我认为了解此行为背后的原因是有益的。

编辑:这是面点,但有可能是没有理由通过argc在这种情况下的参考:你不救,因为内存的指针和int很可能是相同的尺寸或者更糟糕,并且它向读者建议您可以在Main函数中修改argc,其方式需要在main中反映出来,我假定Main被调用,我猜我猜想不是这种情况。

1

你有一个典型的普通的多重定义错误,这是由于你的定义了一个变量在头文件中有外部链接(然后将该头文件包含到多个翻译单元中) 。命名空间与它无关,并且没有任何区别。

当你添加extern关键字你转身所有这些定义非定义声明头。链接器错误立即变得不同。现在,而不是多重定义错误,你有一个缺少定义的错误。

在标题中添加extern关键字是朝正确方向迈出的一步。现在,你只需要创建一个定义了变量

int (*Main)(int& argc, char** argv); 
在一个

(且只有一个)实现文件。