Этот вопрос возник из этот.
У меня есть рабочая программа, которая должна быть разбита на несколько частей. В этой программе необходимо многократно использовать переменную (теперь это 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. Он описывает, как сделать переменные доступными, сделав их глобальными.
Этот ответ был очень полезен, он отлично работал не только с массивами символов, но и с int
s, string
переменные s и GTK + (или указатели на переменные: P).
Но так как этот метод не рекомендуется, я хотел бы поблагодарить всех, кто мог бы показать, как правильно разделить код, передавая переменные в качестве параметра функции, или какой-либо другой метод, более рекомендуемый, чем метод — работающих — глобальных переменных.
Я исследовал параметры и классы, но я новичок, и я испортил код без хорошего результата.
Спасибо за любую помощь.
Определение класса или структуры в заголовочном файле — путь, затем включите заголовочный файл во все исходные файлы, которым нужны классы или структуры. Вы также можете поместить прототипы функций или макросы препроцессора в заголовочные файлы, если они нужны для нескольких исходных файлов, а также для переменных декларации (например. 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
Вам нужно дать параметр в качестве ссылки, если вы хотите тот же компилятор, что и глобальная переменная
#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
Я предпочитаю предоставлять функциональный интерфейс для глобальных данных.
.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;
}
Если вы не планируете изменять переменную, обычно это можно сделать глобальным. Однако лучше всего объявить его с помощью ключевого слова const, чтобы сообщить компилятору, что он не должен быть изменен, например:
const int ENTERO = 10;
Если вы используете несколько файлов cpp, также подумайте об использовании заголовочного файла для ваших структур и объявлений функций.
Если вы планируете модифицировать переменную, просто передайте ее в параметрах функции.