Подтвердить что ты не робот

Как объявить и определить глобальные переменные, чтобы правильно их получить из всех заголовков/исходных файлов

Ну, я изучаю С++ и никогда не научился делать вещи, которые не являются OO. Я пытаюсь получить немного больше опыта программирования в стиле C.

GobalInformation.h

#pragma once

#ifndef GLOBALINFORMATION_H
#define GLOBALINFORMATION_H

#include "MapInformation.h"

namespace gi {
    MapInformation mapInf;
};

#endif

Я хотел бы иметь доступ к gi:: mapInf из каждого заголовка и cpp в моем проекте. Сейчас я включаю globalinformation.h в каждый заголовок, поэтому я получаю ошибки компоновщика с несколькими определениями.

Как я могу решить проблему?

4b9b3361

Ответ 1

В файле заголовка делайте

namespace gi {
    extern MapInformation mapInf;
};

В CPP файле содержится фактическое определение.

namespace gi {
    MapInformation mapInf;
};

Он будет работать так, как вы планируете.

Если вы используете MapInformation для границ библиотек динамической ссылки, вам может потребоваться связать с библиотекой, которая содержит файл cpp определения. Также в окне вам может понадобиться dllimport/dllexport

Ответ 2

Имейте в виду, что наличие глобалов в нескольких единицах компиляции может легко привести к проблемам с порядком инициализации. Вы можете рассмотреть возможность замены каждого глобального на функцию, возвращающую ссылку. В вашем случае поместите это в один файл cpp и объявите его в заголовке:

namespace gi {
    MapInformation& getMapInf()
    {
        static MapInformation result;
        return result;
    }
}

Ответ 3

Возможно, лучшим решением является создание глобального объекта, который содержит все ваши глобальные данные. Затем передайте умный указатель на классы, которые действительно должны получить доступ к этим общим глобальным данным. Пример:

class GlobalData
{
public:
    int ticks_;
};   


//Other file
class ThatNeedsGlobalData
{
public:
ThatNeedsGlobalData(std::shared_ptr<GlobalData> globalData);
};

Это избавит вас от некоторых проблем.

Удачи!

Ответ 4

Глобальными переменными являются C, а пространства имен - С++. Существует хорошая дискуссия об использовании глобальных переменных и о том, как их можно заменить шаблоном Singleton: Globals and Singletons

И вот простой пример: CPP/Classes/Singleton

Ответ 5

Вот несколько вещей, которые вам нужно позаботиться, пытаясь использовать глобальные переменные так, как вы использовали.

  • Убедитесь, что все файлы заголовков, которые содержат файлы заголовков, которые включают GobalInformation.h, также включены внутри #ifndefs. (Я не мог видеть mapinformation.h, поэтому я предполагаю, что вы это сделали)

  • Как и CPP, компилятор C также не обеспечивает порядок инициализации переменных в разных единицах перевода (разные файлы C/CPP). Следовательно, объявите заголовочный файл как

    //GlobalInformation.h
    
    namespace gi {
        extern MapInformation mapInf;
    };
    
  • В функции, которая, как вы знаете, будет вызываться, сначала инициализирует переменную. Таким образом, ленивая инициализация также может быть достигнута в C.