Как сделать переменную доступной для нескольких файлов .cpp, используя класс?

Этот вопрос возник из этот.

У меня есть рабочая программа, которая должна быть разбита на несколько частей. В этой программе необходимо многократно использовать переменную (теперь это GTK + one: P) в частях программы, которые в конечном итоге окажутся в отдельных файлах .cpp.

Итак, я сделал простой пример, чтобы понять, как сделать переменные доступными для частей программы. Модифицированная версия предыдущего кода будет:

#include <iostream>

using namespace std;

int entero = 10;

void function()
{
cout<<entero<<endl;
//action1...;
}

void separated_function()
{
cout<<entero<<endl;
//action2...;
}

int main( int argc, char *argv[] )
{
function();
separated_function();
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}

Нужно правильно разделить код, чтобы function(), another_function() а также main() в отдельных файлах .cpp, и сделать entero доступно для всех них … НО:

В предыдущем вопросе @NeilKirk прокомментировал:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (И я также нашел много веб-страниц, указывающих, что не рекомендуется использовать глобальные переменные).

И, насколько я понимаю, в ответе @PaulH. Он описывает, как сделать переменные доступными, сделав их глобальными.
Этот ответ был очень полезен, он отлично работал не только с массивами символов, но и с ints, stringпеременные s и GTK + (или указатели на переменные: P).

Но так как этот метод не рекомендуется, я хотел бы поблагодарить всех, кто мог бы показать, как правильно разделить код, передавая переменные в качестве параметра функции, или какой-либо другой метод, более рекомендуемый, чем метод — работающих — глобальных переменных.

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

Спасибо за любую помощь.

1

Решение

Определение класса или структуры в заголовочном файле — путь, затем включите заголовочный файл во все исходные файлы, которым нужны классы или структуры. Вы также можете поместить прототипы функций или макросы препроцессора в заголовочные файлы, если они нужны для нескольких исходных файлов, а также для переменных декларации (например. extern int some_int_var;) а также namespace деклараций.

Вы не получите множественные ошибки определения при определении классов, потому что классы — это концепция, которую должен обрабатывать компилятор, сами классы никогда не передаются для компоновщика, где возникают множественные ошибки определения.


Давайте рассмотрим простой пример с одним заголовочным файлом и двумя исходными файлами.

Сначала файл заголовка, например myheader.h:

#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice

// Define a namespace
namespace foo
{
// Define a class
class my_class
{
public:
my_class(int val)
: value_(val)
{}

int get_value() const
{
return value_;
}

void set_value(const int val)
{
value_ = val;
}

private:
int value_;
};

// Declare a function prototype
void bar(my_class& v);
}

#endif // MYHEADER_H

Приведенный выше заголовочный файл определяет пространство имен foo и в пространстве имен класс my_class и функция bar,

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

Затем первый исходный файл, например main.cpp:

#include <iostream>
#include "myheader.h"  // Include our own header file

int main()
{
using namespace foo;

my_class my_object(123);  // Create an instance of the class

bar(my_object);  // Call the function

std::cout << "In main(), value is " << my_object.get_value() << '\n';

// All done
}

И, наконец, второй исходный файл, например, bar.cpp:

#include <iostream>
#include "myheader.h"
void foo::bar(foo::my_class& val)
{
std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
val.set_value(456);
}

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

В foo :: bar () значение равно 123
В main () значение 456
1

Другие решения

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

#include <iostream>

using namespace std;// renamed the parameter to avoid confusion ('entero' is valid though)
void function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value
//action1...;
}

void separated_function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value again
//action2...;
}

int main( int argc, char *argv[] )
{
int entero = 10; // initializing the variable

// give the parameter by reference => the functions will be able to modify its value
function(entero);
separated_function(entero);

cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}

выход:

10
11
12
2

Я предпочитаю предоставлять функциональный интерфейс для глобальных данных.

.h файл:

extern int get_entero();
extern void set_entero(int v);

.файл cpp:

static int entero = 10;

int get_entero()
{
return entero;
}

void set_entero(int v)
{
entero = v;
}

Затем везде используйте эти функции.

#include "the_h_file"
void function()
{
cout << get_entero() << endl;
//action1...;
}

void separated_function()
{
cout << get_entero() << endl;
//action2...;
}

int main( int argc, char *argv[] )
{
function();
separated_function();
cout<< get_entero() <<endl;
//something else with the mentioned variables...;
return 0;
}
1

Если вы не планируете изменять переменную, обычно это можно сделать глобальным. Однако лучше всего объявить его с помощью ключевого слова const, чтобы сообщить компилятору, что он не должен быть изменен, например:

const int ENTERO = 10;

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

Если вы планируете модифицировать переменную, просто передайте ее в параметрах функции.

0
По вопросам рекламы [email protected]