Как разделить переменную между несколькими исходными файлами в C ++? - PullRequest
0 голосов
/ 20 марта 2020

Сводка моей цели

Я хочу создать глобальный экземпляр объявленного класса, совместно используемый несколькими .cpp файлами в C ++ .

Пояснения

Если вы хотите быстро набрать go, вы можете прыгнуть сразу после Ожидания .

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

Шаг 1:
Я делал программу C ++ с классом, определенным в заголовочном файле.
(Функции класса были объявлены в файле cpp.)

Чтобы объяснить это, Я буду использовать упрощенный гипотетический код. (Не факт.)

Код упрощенного гипотетического Class.h:

class Class {
    public:
        Class(intx,int y); //Does a lot of things

        int OP1(int x); //Dummy operation
        int OP2(int x); //Dummy operation
    private:
        type ManyVars;
}

Код упрощенного гипотетического main.cpp

#include "Class.h"

Class Member(140,360);  //Declares it with parameters

bool Func1(int x) { //Dummy function
    int y = Member.OP2(x);
    return x > Member.OP1(y);
}

bool Func2(int x) { //Dummy function
    int y = Member.OP2(x) * x;
    return x > Member.OP1(y) +1;
}


int main() {
    int x;

    std::cin >> x;

    y = Func2(x);
    z = Func1(y * x / 5);

    return Func2(z) + x / y;
}

Насколько я был, все работало нормально, но код был чудовищно большим в main.cpp, потому что у меня было более 16 функций, включая 2 большие!
(я показываю в моем примере только две функции, чтобы быть простым.)

Шаг 2:
Чтобы облегчить чтение кода , я переместился маленькие функции в двух других файлах Funcs.cpp и Funcs.h, как библиотека .
Затем я переместил большие функции в новый файл .cpp для каждого из них после включения в другой заголовочный файл.
(скрыт в примере, потому что это похоже на Funcs.cpp.)

Итак, теперь гипотетический main.cpp выглядит следующим образом:

#include "Class.h"
#include "Funcs.h"

Class Member(140,360);

int main() {
    int x;

    std::cin >> x;

    int y = Func2(x);
    int z = Func1(y * x / 5);

    return Func2(z) + x / y;
}

И гипотетический Funcs.cpp выглядит так:

#include "Class.h"
#include "Funcs.h"

bool Func1(int x) {
    int y = Member.OP2(x);
    return x > Member.OP1(y);
}

bool Func2(int x) {
    int y = Member.OP2(x) * x;
    return x > Member.OP1(y) +1;
}

Теперь возникает проблема: Member только определено в main.cpp , но оно мне нужно и в * 108 7 * (и другие файлы функций тоже) .

Шаг 3:
Я попытался добавить другое входное значение типа Class для каждой функции и вставьте Member в него при использовании. Это работает, но функции выглядят ужасно ! Мне не нужен дополнительный параметр для каждой функции! Поэтому я на данный момент вернул код к шагу 1.

Ожидания

То, что я хочу, это любой способ делят один и тот же экземпляр между ними . Это в основном глобальная переменная.
Я хочу сохранить те же функции. int y = Member.OP2(x) не должен изменяться , тогда как начало каждого файла может быть изменено .
Я хотел бы иметь возможность объявить несколько таких Member s (я выиграл ') т, но это должно быть возможно сделать).

Кто-нибудь знает способ обмена экземплярами таким образом?

Пожалуйста, скажите мне, если что-то неясна.

Ответы [ 2 ]

5 голосов
/ 20 марта 2020

Member - глобальная переменная. Поделитесь им, используя обычную технику, которую вы использовали бы для любой глобальной переменной, объявите ее в файле заголовка и определите его (один раз) в исходном файле.

В файле заголовка (скажем Class.h)

extern Class Member;

В основном. cpp

Class Member(140,360);

Вот и все.

0 голосов
/ 20 марта 2020

Альтернативным способом использования глобальных переменных является использование шаблона Singleton путем хранения уникального экземпляра класса в хранилище c ( Построение по идиоме первого использования ).

Существует вопрос , который объясняет разницу между этим и ответом Джона (c .f. FAQ по C ++, в котором рассматривается, что такое фиаско порядка инициализации и как этому подходу избежать этого ).

template<int x, int y>
class Class
{
public:
    static Class & get_instance()
    {
        static Class instance; // <- called only once!
        return instance;
    }

    Class(const Class &) = delete;

    Class & operator=(const Class &) = delete;

    bool OP1(int a)
    {
        return a > x;
    }

    bool OP2(int b)
    {
        return b > y;
    }

private:
    Class() = default;

    ~Class() = default;
};

Затем вы можете получить ссылку на экземпляр методом get_instance() как

auto& Member = Class<140,360>::get_instance();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...