1

This question has derived from this one.

I have a working program which must be split into multiple parts. In this program is needed to use a variable (now it's a GTK+ one :P) many times in parts of the program that will end up in separated .cpp files.

So, I made a simple example to understand how to make variables available to the program parts. A modified version of the previous code would be:

#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;
    }

It is needed to split the code correctly, to have function(), another_function() and main() in separated .cpp files,and make entero avaliable to all of them... BUT:

In the previous question @NeilKirk commented:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (And I also have found many web pages pointing that is not recommended to use global variables).

And, as far I can understand, in the answer provided by @PaulH., he is describing how to make variables avaliable by making them global. This answer was very useful, it worked fine not only with char arrays, but also with ints, strings and GTK+ variables (or pointers to variables :P).

But since this method is not recommended, I would thank anyone who could show what would be the correct way to split the code passing the variables as a function parameter or some other method more recommended than the - working - global variables one.

I researched about parameters and classes, but I'm a newbie, and I messed the code up with no good result.

3
  • You do know you can create you own header files, and include them in multiple source files? The header file can contain declarations and class or structure definitions. Commented Sep 23, 2015 at 4:32
  • Yes, but the purpose of this files is to compile them together, and including the same variables in all of them would generate a multiple definition at compiling time. And I don't really understand how to make what you are saying, I tried but I failed miserably. Commented Sep 23, 2015 at 4:34
  • Closely related to How to make char array available in multiple .cpp files Commented Nov 29, 2021 at 17:55

4 Answers 4

2

You need to give the parameter as a reference if you want the same comportement as a global variable

#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;
}

output:

10
11
12
Sign up to request clarification or add additional context in comments.

3 Comments

The variable is supposed to be the same in all functions including main(), even when the value could change. The matter is where should it be declared, defined and how to pass it to the functions.
@Fahedsl By passing the variable by reference it will be the same in all functions including main(). The answer does show how to declare, define and pass the variable to the functions.
@Zermingore . +1. Ok, I tried around and now I understand it, Thank you very much for you answer. :)
1

Defining a class or struct in a header file is the way to go, then include the header file in all source files that needs the classes or structures. You can also place function prototypes or preprocessor macros in header files if they are needed by multiple source files, as well as variable declarations (e.g. extern int some_int_var;) and namespace declarations.

You will not get multiple definition errors from defining the classes, because classes is a concept for the compiler to handle, classes themselves are never passed on for the linker where multiple definition errors occurs.


Lets take a simple example, with one header file and two source files.

First the header file, e.g. 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

The above header file defines a namespace foo and in the namespace a class my_class and a function bar.

(The namespace is strictly not necessary for a simple program like this, but for larger projects it becomes more needed.)

Then the first source file, e.g. 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
}

And finally the second source file, e.g. 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);
}

Put all three files in the same project, and build. You should now get an executable program that outputs

In foo::bar(), value is 123
In main(), value is 456

1 Comment

+1. Thanks for your answer, I took a bit to understand it, since I'm newbie ( :D ). Now I got it, and helped me a lot.
1

I prefer to provide a functional interface to global data.

.h file:

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

.cpp file:

static int entero = 10;

int get_entero()
{
   return entero;
}

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

Then, everywhere else, use those functions.

#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;
}

2 Comments

Why declare the functions extern? They have external linkage by default right?
@ChrisDrew, Yes, they do. It's a stylistic preference. It's either extern or static. Making it explicit makes the code base consistent.
0

If you do not plan to modify the variable, it is generally ok to make it global. However, it is best to declare it with the const keyword to signal the compiler that it should not be modified, like so:

const int ENTERO = 10;

If you are using multiple cpp files, also consider using a header file for your structures and function declarations.

If you are planning on modifying the variable, just pass it around in function parameters.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.