how to declare and initialize variables off main.cpp for use on main.cpp

I have 30+ variables grouped together in my main.cpp that I would like to move the declaration and initialization of which to another file. I've tried creating an .h file and moving them there and it works fine. I don't have a need to modify them for global use, just off main.cpp storage. Trying to declutter the main.cpp is my primary goal; maybe making a namespace to account for what the variables might be for someone reading through the code.

Just wanted to put the question out there before committing to one course of action. What should "my design" be for this juncture?

vars.h //moved from main
1
2
3
4
5
6
7
8
9
10
#ifndef VARS_H
#define VARS_H

int a = 5;
int b = 2;
int c = 34;
int aa = 50;
int bb = 20;

#endif 

1
2
3
4
5
6
7
8
main.cpp

#include "vars.h"
using namespace std;
..

..
std::cout<<aa * bb<<std::endl;
Last edited on
You plan to have:
1
2
3
4
5
6
7
8
// these are global variables
// with lifetimes of globals
int aa = 50;
int bb = 20;

int main() {
  aa * bb;
}


cf.
1
2
3
4
5
6
7
8
9
struct Foo {
  int aa = 50;
  int bb = 20;
};

int main() {
  Foo f; // this is local variable with automatic storage duration
  f.aa * f.bb;
}


Some global variables, like std::cout and std::cin, are understandable, but for others you need a better rationale than "I don't want much code in my files".
I don't want much code in my files


Its not that I don't want much code in my files. Its that I want it to be readable, organized. So I'm thinking in this case can I do my declaration and initialization away from main. I'm now thinking namespace or class? I've got 20-30 vars in several lines that are just a mess.

Then again maybe what you are hinting at is to stop perfecting where its not needed. If that is true I would need to hear that as well.
It just depends on what you want the code to look like in that scenario.

Namespaces are an option, and a singleton is also an option.

Singletons also have the functionality if you use it with polymorphism you are capable of reducing code bloat if only your functions interact with the inner data, but note that code bloat is a complex topic, and polymorphism can be used without singletons.

Keep in mind you should have only 1 singleton (because some programmers dislike excessive use of singletons because singletons can break just as easily as global variables), and with that one singleton you can point to other class subsystems that you create inside it.
you can #include them where you want them. This scopes them to where you put them.

eg

int main()
{
#include vars.txt
//its as if the code in that file were actually RIGHT HERE.
}

int foo()
{
#include vars.txt
//this is another local VERSION of them; not the same variables but the same NAMES. Not terribly useful, is it?
}

I would not do this (its a good trick for inline force of functions in embedded real time coding where the compiler is arguing about inline).

I would put all your variables in a struct with a default constructor to set the values. This makes it portable; you can define the struct in main and pass it by reference anywhere else you need it. If you don't make it a singleton, you can have a copy of it for whatever reason if that makes sense.

that looks like
struct vars
{
#include vars.txt //you can do this or you can put them here directly as you see fit.
};

int main()
{
vars v;
v.whatever = whateverelse;
foo(v); //!!! useful!
}

void foo(vars &v2)
{
v2.whatever = yetanother;
}

// and if not a singleton

v makemoreofthem()
{
vars a_copy; //not sure why you might want to create a new set of them, but you could.
...
return a_copy;
}

you can mix and match a variety of ideas; the struct can be in a namespace if you want (though the struct itself is close to that functionality).

another approach, if most of the variables are the same type, is an enumed array. this has a lot of benefits and I have used it frequently.
looks like this: (type can be a union, and then you can really have some 'fun')
enum{var1, var2, var3, ... e_max};
vector<type> vars(e_max);

vars[var1].unionfieldtypename = value; //etc
this can be neat for iteration, serialization, compactness, and so on. But it may or may not be a pattern that makes sense to your needs. There are downsides, eg wasted memory if unioned. Among its coolness features, adding a variable in front of e_max costs nothing but a recompile.

in your example, all are ints, so union isnt needed.
then its just
enum{...}
vector<int> vars(e_max);
vars[aa] = 3; //etc
Last edited on
Could this #include vars.txt be simply as vars.h?
yes, but .h implies things. It would probably be a mystery to many readers if you had a #include vars.h in your main() function. And worse, if it were above main, you would be creating globals and no end of problems and bad practice with that, so simply moving your include statement changes behavior dramatically.

having a different, non c++ connotations file extension alerts the user that you are doing something unusual.

the name of the file does not matter.

Again, for a dozen reasons, I can't recommend enough using one of the other solutions; a struct or the enum-vector setup, or whatever else. you lose capability with the # approach -- you can't pass the variable block around, and that should be a flag that its not a great solution.

The solutions I suggested add no more code than your #ifdefs that would go away. Its not complicated to do them, and if the size of the code is the concern, the enum approach is microscopic (well, the enum itself is large, but you can put most of it on 2-3 lines).
if these are actually constants and not variables, you can condense it even more, of course (?).
Last edited on
Filenames are not important. Anything goes. Only build-tools or IDE makes assumptions based on the extensions.
Are these global variables related somehow? If the only relation is that they all appear in main, then maybe they should all be separate and local to main (or, if necessary, global).

If there is a relationship between them, then encapsulation philosophy would strongly suggest that they be made into a struct or a class. You could even write a constructor to initialize the values. And as you use the data more and see more relationships, you can add member functions to the struct/class, keeping the functions with the data.
i know my answer would be off topic from the above answers but,
1)I would suggest you that if want readability assign proper names,the location or declarations doesnt matter,

2)keep extra space between variables and lines,

3)usually the reason for classes or functions are separated in header and .cpp/.cc/.c files is because mostly for hiding the implementation for optimal space usage declare a variable where you want

4)if they are constants and not gonna change declare them that way

5)use a naming convention

if you are declaring it in a other file that means they would all become global values,only move those variables if they are meant to be global,
or
you could as above jonnin said declare a struct in another file and create the object of the structure where you want





Last edited on
Thank you, I have a lot to study. It might be that the answer is to keep the variables local but simply do a good job of renaming them to take any of the ambiguity out of their existence -- or declare a struct in another file

you could as above jonnin said declare a struct in another file and create the object of the structure where you want


I'll start above/here

If there is a relationship between them, then encapsulation philosophy would strongly suggest that they be made into a struct or a class. You could even write a constructor to initialize the values. And as you use the data more and see more relationships, you can add member functions to the struct/class, keeping the functions with the data.
Last edited on
Topic archived. No new replies allowed.