【问题标题】:Undefined Reference/ Multiple Definition for namespace extern variable , c++ structuring issue命名空间外部变量的未定义参考/多重定义,C++ 结构问题
【发布时间】:2014-02-05 15:07:13
【问题描述】:

我正在创建一个命名空间来帮助我调试程序,但我在弄清楚如何构建所有内容并让它毫无问题地构建时遇到了问题。

这是我当前的标题:

#ifndef HELPER_H
#define HELPER_H
#include <string>
#include <fstream>
#include <sstream>

namespace Helper
{
    enum LOG { ONSCREEN, OFFSCREEN };
    extern std::ofstream logfile;
    //std::ofstream logfile("log.txt", std::ios_base::out | std::ios_base::app );


    void EnableLogging();
    void Log(std::string s, LOG type);

    template <class T>
    std::string ToString(const T& t)
    {
        std::ostringstream sstr;
        sstr << t;
        return sstr.str();
    }
}

#endif // HELPER_H

这是帮助程序 cpp 文件:

#include "Helper.h"
#include <cstdio>

void Helper::EnableLogging()
{
    #ifdef WIN32
        // To use console on pc
    std::ofstream ctt("CON");
    freopen("CON", "w", stdout);
    freopen("CON", "w", stderr);
    #endif
    #ifdef GP2X
        //To log to text file on the caanoo
    logfile.open("log.txt", std::ios_base::out | std::ios_base::app );
    #endif

}

void Helper::Log(std::string s, LOG type)
{
    if(type == OFFSCREEN)
    {
        #ifdef GP2X
        //log << "L" << __LINE__ << "|T" << SDL_GetTicks() << "| " << s << std::endl;
        logfile << s << std::endl;
        #endif
        #ifdef WIN32
        printf("%s",s.c_str());
        #endif
    }
}

目前我收到 undefined reference to Helper::logfile 错误,我完全理解这是因为我使用了 extern 关键字。

如果没有 extern 关键字,我会得到一个不同的错误:Helper::logfile 的多重定义。该错误在我试图include "Helper.h" 的另一个源文件中报告为 'first defined..'。报告错误的行号是所述源文件中的构造函数,但我怀疑这与任何事情都没有关系。

我确定我在编译时构建了错误的帮助代码,但我不知道应该怎么做?

【问题讨论】:

  • 日志文件最初是在哪里声明的?我看到一个 extern,所以该声明可能不在 Helper 命名空间内。
  • @ArthurChamz 我可以肯定地说,extern std::ofstream logfile 是唯一一次声明这样的变量。我尝试初始化它的(唯一)地方是logfile.open("log.txt", std::ios_base::out | std::ios_base::app );,而我唯一使用它的地方是Helper::LogHelper::LogHelper::EnableLogging 仅在我提到的其他项目源文件中调用一次。感谢您查看它!

标签: c++ compiler-construction header namespaces declaration


【解决方案1】:

您需要像您一样在标题中声明变量,以使名称在需要时可用。

// Helper.h
extern std::ofstream logfile;

你需要在源文件中定义它;单一定义规则要求您只有一个定义。

// Helper.cpp
std::ofstream Helper::logfile("log.txt", std::ios_base::out | std::ios_base::app );

没有定义,变量不存在,因此出现“未定义引用”错误。

在标头中有定义,它是在包含标头的每个翻译单元中定义的,因此会出现“多重定义”错误。

在一个源文件中定义,定义一次,链接器很高兴。

【讨论】:

  • 谢谢!我知道这一点,但我一直在努力解决我认为围绕定义的语法。我现在刚刚像您一样在源文件范围的顶层定义了定义,并且编译得很好。 (以前我试图将它包含在命名空间大括号中,但没有运气)。塔!
猜你喜欢
  • 2022-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2021-02-01
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多