Неопределенная ссылка / множественное определение для внешней переменной пространства имен, проблема структурирования c ++

0

Я создаю пространство имен, чтобы помочь мне отлаживать программу, но у меня возникли проблемы с выяснением структуры структуры и ее создания без проблем.

Здесь мой текущий заголовок:

#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 Helper:

#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
    }
}

На данный момент я получаю неопределенную ссылку на ошибку Helper :: logfile, которую я полностью понимаю, потому что я использовал ключевое слово extern.

Без ключевого слова extern возникает другая ошибка: множественное определение Helper :: logfile. Ошибка сообщается как "first defined.." в другом исходном файле, в который я пытаюсь include "Helper.h". Номер строки, о которой сообщается об ошибке, является конструктором в указанном исходном файле, но я подозреваю, что имеет мало делать с чем угодно.

Я уверен, что я неправильно структурирую код помощника для компиляции, но я не могу понять, как я должен это делать?

  • 0
    Где был первоначально объявлен файл журнала? Я вижу экстерн, так что, возможно, объявление не находится в пространстве имен Helper.
  • 0
    @ArthurChamz Я могу с полной уверенностью сказать, что extern std::ofstream logfile - единственный раз, когда такая переменная объявляется. Единственное место, которое я пытаюсь инициализировать, это logfile.open("log.txt", std::ios_base::out | std::ios_base::app ); и единственное место, где я когда-либо использовал его, находится в Helper::Log . Helper::Log и Helper::EnableLogging вызываются только один раз, из упомянутого мной другого исходного файла проекта. Спасибо, что взглянули на это!
Теги:
namespaces
header
compiler-construction
declaration

1 ответ

2
Лучший ответ

Вам нужно объявить переменную в заголовке, как и вы, чтобы сделать имя доступным там, где оно необходимо.

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

Вы должны определить его в исходном файле; в правиле одного определения требуется, чтобы у вас было ровно одно определение.

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

Без определения переменная не существует, следовательно, ошибка "неопределенной ссылки".

С определением в заголовке он определяется в каждой единицы перевода, которая включает заголовок, следовательно, ошибка "множественного определения".

С определением в одном исходном файле он определен один раз, и компоновщик счастлив.

  • 0
    Спасибо! Я знал это, но я боролся с синтаксисом, который я предполагаю вокруг определения. Теперь я только что добавил определение на верхнем уровне области видимости исходного файла, как вы сделали, и оно отлично скомпилировано. (Раньше я пытался заключить его в фигурные скобки, но мне не повезло). Та!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню