Is this code with global variables good practice?
Your doubt is correct, don't use global variables.

(Note: For this post, I mean variable in its true meaning, i.e. objects that may change.)

I can't say for sure which technique is the correct one without seeing your code, but normally you want to pass the variable as a parameter to whichever entity needs it:

void foo(Input input)
{
    input.doSomething();
}

int main()
{
    Input input;
    input.doSomething();

    foo(input);
}


Or, restrict it to a class as a member variable.



Update: Class examples

You can do it one or both of these ways:

class Person {
    std::string name_;
public:
    explicit Person(std::string const&amp; name) : name_(name) {}
    void set_name(std::string const&amp; name) { name_ = name; }
}

void foo()
{
    Person p("Bob Loblaw");

    p.set_name("Slartibartfast");
}




There are two key downsides to using global variables:

1. They can be changed everywhere.

You generally want to enlist the compiler's aid in finding bugs and errors for you. If you allow yourself to modify a variable from all over your code, it is very hard for your compiler and yourself to track down an error. Consider the following scenario:

Input input; // global

void foo()
{
    Input inputt;
    input = someThingWeird;
}


This code will compile. If you're really unlucky, it will even work for a while. If you don't have a global, the code won't compile and the bug will be easy to find.

2. They increase coupling (and reduce testability).

By reading from a global variable, your entity (i.e. function, class, whatever) depends on that global variable. If some day you want to use something else, you'll have to do a lot of refactoring. What's more important, if you change an aspect of the global variable, you will need to update all parts of the code that uses it. This is a great opportunity for suble bugs to infiltrate your code and make your life miserable. A typical example is that you modify one part of your code, and a completely different part will break.

Using globals also makes your code hard to unit test, because it depends on the global variable.