In a class header file Texture.h I declare a static const int.
static const int MAX_TEXTURE_SLOTS;
In Texture.cpp I define the variable as 0.
const int Texture::MAX_TEXTURE_SLOTS = 0;
Now in Window.cpp class's constructor I attempt to assign to the variable using an out parameter, however this obviously does not compile as &Texture::MAX_TEXTURE_SLOTS points to a const int* and not an int* .
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &Texture::MAX_TEXTURE_SLOTS);
I have tried using const_cast, but am greeted with a segmentation fault on runtime.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, const_cast<int*>(&Texture::MAX_TEXTURE_SLOTS));
I have also tried directly casting to an int * but once again, seg fault.
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, (int*)&Texture::MAX_TEXTURE_SLOTS);
Many thanks.
EDIT 2: So since you're trying to abstract OpenGL contexts, you'll have to let go of the "traditional" constructor/destructor idioms. And just for your information (unrelated to this question): OpenGL contexts are not tied to windows! As long as a set of windows and OpenGL contexts are compatible with each other, you may mix and match any way you like. But I digress.
The standard idiom to deal with a situation like yours is to use preinitializing factory functions. Like this:
class MyOpenGLContextWrapper {
public:
// Yes, shared_ptr; using a unique_ptr here for objects that are kind
// of a nexus for other things -- like an OpenGL context -- just creates
// a lot of pain and misery. Trust me, I know what I'm talkink about.
typedef std::shared_ptr<MyOpenGLContextWrapper> ptr;
struct constdata {
NativeGLContextType context;
// ...
GLint max_texture_image_units;
// ...
};
static ptr create();
protected:
MyOpenGLContextWrapper(constdata const &cdata) : c(cdata) {};
virtual ~MyOpenGLContextWrapper();
constdata const c;
}
MyOpenGLContextWrapper::ptr MyOpenGLContextWrapper::create()
{
struct object : public MyOpenGLContextWrapper {
object(MyOpenGLContextWrapper::constdata const &cdata) : MyOpenGLContextWrapper(cdata) {}
~object(){}
};
MyOpenGLContextWrapper::constdata cdata = {};
// of course this should all also do error checking and failure rollbacks
cdata.context = create_opengl_context();
bind_opengl_context(cdata.context);
// ...
glGetInteger(GL_MAX_TEXTURE_IMAGE_UNITS, &cdata.max_texture_image_units);
return std::make_shared<object>(cdata);
}
EDIT: I just saw that you intend to use this to hold on to a OpenGL limit. In that case you can't do this on a global scope anyway, since those values depend on the OpenGL context in use. A process may have several OpenGL contexts, each with different limits.
On most computer systems you'll encounter these days, variables declared const in global scope will be placed in memory that has been marked as read only. You literally can't assign to such a variable.
The usual approach to implement global scope runtime constants is by means of query functions that will return from an internal or otherwise concealed or protected value. Like
// header.h
int runtime_constant();
#define RUNTIME_CONSTANT runtime_constant()
// implementation.c / .cpp
int runtime_constant_query(){
static int x = 0;
// NOTE: This is not thread safe!
if( !x ){ x = determine_value(); }
return x;
}
You can then fetch the value by calling that function.
Provided that glGetIntegerv doesn't depend on other gl* functions being called before, you may use an immediately-invoked lambda:
// Texture.cpp
const int Texture::MAX_TEXTURE_SLOTS = []
{
int maxTextureSlots{0}:
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &maxTextureSlots);
return maxTextureSlots;
}();
You don't.
You can't assign to a const outside of its definition. Also, using a const variable where the const has been const_casted away is UB. This also means you can't directly initialize a const variable with an output parameter. For trivial types, just output to another variable and make a const copy if you so wish.
If you were the author of the function you're calling, you would do well not to use out parameters, and then you could assign to const variables directly, perhaps using structured bindings if you want to name multiple of the outputs at a time. But here, you're not.
For a unique id for some object I can create a counter in two ways but I don't know which one is better while they are quite different in code (though maybe not in byte code, I have no idea).
The first way would be to have some function which uses a static variable:
Header:
unsigned int GetNextID();
cpp:
unsigned int GetNextID()
{
static unsigned id{0};
return id++;
}
The other option:
Header:
class UniqueIdGenerator
{
public:
static unsigned int GetNextID();
private:
static unsigned int mID;
}
cpp:
unsigned int UniqueIdGenerator::mID = 1;
unsigned int UniqueIdGenerator::GetNextID()
{
return ++mID;
}
FYI, I've read that the former is not thread safe, but I don't see why the latter would be either. If anything, I like the simple function more as it's simpler & shorter.
To make it thread-safe you should change to std::atomic<unsigned> mID, and write your function as
return mID.fetch_add(1);
Which version you choose shouldn't matter, although in my opinion the free function would be the one I'd prefer as it's not possible to access the variable outside of the function.
The difference is scope/visibility of the static variable. A class member can be shared by more than one method, the variable in the method cannot.
On the principle that data should be as private as possible, the static variable in the method is safer if it meets your needs.
For a discussion of thread safety when initializing the variable, see this question., but using the variable is not thread safe unless you take some steps to insure that it is protected (either use and atomic (preferred for a simple value), or protect it with a mutex (if there is more than one piece of data that should be protected))
Let us assume the following class:
class FileManipulator
{
static InputTypeOne * const fileone;
InputTypeTwo *filetwo;
public:
FileManipulator( InputTypeTwo *filetwo )
{
this->filetwo = filetwo;
}
int getResult();
};
FileManipulator uses data from both files to obtain output from getResult(). This means multiple iterations over filetwo and multiple constructions of FileManipulators via iterations for different InputTypeTwo objects. Inputs are, let us say, some .csv databases. InputTypeOne remains the same for the whole task.
The program itself is multi-modular and the operation above is only its small unit.
My question is how can I handle that static field in accordance with the object-oriented paradigm and encapsulation. The field must be initialized somehow since it is not a fixed value over different program executions. As far as I understand C++ rules I cannot create a method for setting the field, but making it public and initializing it outside of any class (FileManipulator or a befriended class) seems to me at odds with the encapsulation.
What can I do then? The only thing that comes to my mind is to do it in a C manner, namely initialize it in an isolated enough compilation unit. Is it really all I can do? How would that be solved in a professional manner?
edit
I corrected pointer to constant to constant pointer, which was my initial intention.
You can write a public static method of FileManipulator that would initialize the field for you:
static void init()
{
fileone = something();
}
And then call it from main() or some place where your program is being initialized.
One way of doing this which comes to mind is:
In the .cpp file
FileManipulator::fileone = NULL;
Then modify constructor to do the following:
FileManipulator( InputTypeTwo *filetwo, InputTypeOne *initValue = NULL)
{
if(fileone == NULL)
{
fileone = initValue;
}
this->filetwo = filetwo;
}
Or you could also define an init function and make sure to call it before using the class and after the CTOR. the init function will include the logic of how to init fileone.
So I am new to c++ and I'm writing for a scientific application.
Data needs to be read in from a few input text files.
At the moment I am storing these input variables in an object. (lets call it inputObj).
Is it right that I have to pass this "inputObj" around all my objects now. It seems like it has just become a complicated version of global variables. So I think I may be missing the point of OOP.
I have created a g++ compilable small example of my program:
#include<iostream>
class InputObj{
// this is the class that gets all the data
public:
void getInputs() {
a = 1;
b = 2;
};
int a;
int b;
};
class ExtraSolver{
//some of the work may be done in here
public:
void doSomething(InputObj* io) {
eA = io->a;
eB = io->b;
int something2 = eA+eB;
std::cout<<something2<<std::endl;
};
private:
int eA;
int eB;
};
class MainSolver{
// I have most things happening from here
public:
void start() {
//get inputs;
inputObj_ = new InputObj();
inputObj_ -> getInputs();
myA = inputObj_->a;
myB = inputObj_->b;
//do some solve:
int something = myA*myB;
//do some extrasolve
extraSolver_ = new ExtraSolver();
extraSolver_ -> doSomething(inputObj_);
};
private:
InputObj* inputObj_;
ExtraSolver* extraSolver_;
int myA;
int myB;
};
int main() {
MainSolver mainSolver;
mainSolver.start();
}
Summary of question: A lot of my objects need to use the same variables. Is my implementation the correct way of achieving this.
Don't use classes when functions will do fine.
Don't use dynamic allocation using new when automatic storage will work fine.
Here's how you could write it:
#include<iostream>
struct inputs {
int a;
int b;
};
inputs getInputs() {
return { 1, 2 };
}
void doSomething(inputs i) {
int something2 = i.a + i.b;
std::cout << something2 << std::endl;
}
int main() {
//get inputs;
inputs my_inputs = getInputs();
//do some solve:
int something = my_inputs.a * my_inputs.b;
//do some extrasolve
doSomething(my_inputs);
}
I'll recommend reading a good book: The Definitive C++ Book Guide and List
my answer would be based off your comment
"Yea I still haven't got the feel for passing objects around to each other, when it is essentially global variables im looking for "
so this 'feel for passing object' will come with practice ^^, but i think it's important to remember some of the reasons why we have OO,
the goal (in it simplified version) is to modularise your code so as increase the reuse segment of code.
you can create several InputObj without redefining or reassignig them each time
another goal is data hiding by encapsulation,
sometimes we don't want a variable to get changed by another function, and we don't want to expose those variable globally to protect their internal state.
for instance, if a and b in your InputObj where global variable declared and initialized at the beginning of your code, can you be certain that there value doesn't get changed at any given time unless you want to ? for simple program yes.. but as your program scale so does the chances of your variable to get inadvertently changed (hence some random unexpected behavior)
also there if you want the initial state of a and b to be preserved , you will have to do it yourself ( more temp global variables? )
you get more control over the flow of your code by adding level abstractions with classes/inheritances/operation overriding/polymorphisms/Abtract and interface and a bunch of other concepts that makes our life easier to build complex architectures.
now while many consider global variable to be evil, i think they are good and useful when used properly... otherwise is the best way to shoot yourself in the foot.
I hope this helped a bit to clear out that uneasy feeling for passing out objects :)
Is using your approach good or not strongly depends on situation.
If you need some high speed calculation you can't provide incapsulation methods for your InputObj class, though they are recommended, because it will strongly reduce speed of calculation.
However there are two rules that your can follow to reduce bugs:
1) Carefully using 'const' keyword every time you really don't want your object to modify:
void doSomething(InputObj * io) -> void doSomething(const InputObj * io)
2) Moving every action related with initial state of the object(in your case, as far as I can guess, your InputObj is loaded from file and thus without this file loading is useless) to constructor:
Instead of:
InputObj() { }
void getInputs(String filename) {
//reading a,b from file
};
use:
InputObj(String filename) {
//reading a,b from file
};
You are right that this way you have implemented global variables, but I would call your approach structured, and not complicated, as you encapsulate your global values in an object. This will make your program more maintainable, as global values are not spread all over the place.
You can make this even nicer by implementing the global object as a singleton (http://en.wikipedia.org/wiki/Singleton_pattern) thus ensuring there is only one global object.
Further, access the object through a static member or function. That way you don't need to pass it around as a variable, but any part of your program can easily access it.
You should be aware that a global object like this will e.g. not work well in a multithreaded application, but I understand that this not the case.
You should also be aware that there is a lot of discussions if you should use a singleton for this kind of stuff or not. Search SO or the net for "C++ singleton vs. global static object"
Typically, the way I'd define a true global constant (lets say, pi) would be to place an extern const in a header file, and define the constant in a .cpp file:
constants.h:
extern const pi;
constants.cpp:
#include "constants.h"
#include <cmath>
const pi=std::acos(-1.0);
This works great for true constants such as pi. However, I am looking for a best practice when it comes to defining a "constant" in that it will remain constant from program run to program run, but may change, depending on an input file. An example of this would be the gravitational constant, which is dependent on the units used. g is defined in the input file, and I would like it to be a global value that any object can use. I've always heard it is bad practice to have non-constant globals, so currently I have g stored in a system object, which is then passed on to all of the objects it generates. However this seems a bit clunky and hard to maintain as the number of objects grow.
Thoughts?
It all depends on your application size. If you are truly absolutely sure that a particular constant will have a single value shared by all threads and branches in your code for a single run, and that is unlikely to change in the future, then a global variable matches the intended semantics most closely, so it's best to just use that. It's also something that's trivial to refactor later on if needed, especially if you use distinctive prefixes for globals (such as g_) so that they never clash with locals - which is a good idea in general.
In general, I prefer to stick to YAGNI, and don't try to blindly placate various coding style guides. Instead, I first look if their rationale applies to a particular case (if a coding style guide doesn't have a rationale, it is a bad one), and if it clearly doesn't, then there is no reason to apply that guide to that case.
I can understand the predicament you're in, but I am afraid that you are unfortunately not doing this right.
The units should not affect the program, if you try to handle multiple different units in the heart of your program, you're going to get hurt badly.
Conceptually, you should do something like this:
Parse Input
|
Convert into SI metric
|
Run Program
|
Convert into original metric
|
Produce Output
This ensure that your program is nicely isolated from the various metrics that exist. Thus if one day you somehow add support to the French metric system of the 16th century, you'll just add to configure the Convert steps (Adapters) correctly, and perhaps a bit of the input/output (to recognize them and print them correctly), but the heart of the program, ie the computation unit, would remain unaffected by the new functionality.
Now, if you are to use a constant that is not so constant (for example the acceleration of gravity on earth which depends on the latitude, longitude and altitude), then you can simply pass it as arguments, grouped with the other constants.
class Constants
{
public:
Constants(double g, ....);
double g() const;
/// ...
private:
double mG;
/// ...
};
This could be made a Singleton, but that goes against the (controversed) Dependency Injection idiom. Personally I stray away from Singleton as much as I can, I usually use some Context class that I pass in each method, makes it much easier to test the methods independently from one another.
A legitimate use of singletons!
A singleton class constants() with a method to set the units?
You can use a variant of your latter approach, make a "GlobalState" class that holds all those variables and pass that around to all objects:
struct GlobalState {
float get_x() const;
float get_y() const;
...
};
struct MyClass {
MyClass(GlobalState &s)
{
// get data from s here
... = s.get_x();
}
};
It avoids globals, if you don't like them, and it grows gracefully as more variables are needed.
It's bad to have globals which change value during the lifetime of the run.
A value that is set once upon startup (and remains "constant" thereafter) is a perfectly acceptable use for a global.
Why is your current solution going to be hard to maintain? You can split the object up into multiple classes as it grows (one object for simulation parameters such as your gravitational constant, one object for general configuration, and so on)
My typical idiom for programs with configurable items is to create a singleton class named "configuration". Inside configuration go things that might be read from parsed configuration files, the registry, environment variables, etc.
Generally I'm against making get() methods, but this is my major exception. You can't typically make your configuration items consts if they have to be read from somewhere at startup, but you can make them private and use const get() methods to make the client view of them const.
This actually brings to mind the C++ Template Metaprogramming book by Abrahams & Gurtovoy - Is there a better way to manage your data so that you don't get poor conversions from yards to meters or from volume to length, and maybe that class knows about gravity being a form acceleration.
Also you already have a nice example here, pi = the result of some function...
const pi=std::acos(-1.0);
So why not make gravity the result of some function, which just happens to read that from file?
const gravity=configGravity();
configGravity() {
// open some file
// read the data
// return result
}
The problem is that because the global is managed prior to main being called you cannot provide input into the function - what config file, what if the file is missing or doesn't have g in it.
So if you want error handling you need to go for a later initialization, singletons fit that better.
Let's spell out some specs. So, you want:
(1) the file holding the global info (gravity, etc.) to outlive your runs of the executable using them;
(2) the global info to be visible in all your units (source files);
(3) your program to not be allowed to change the global info, once read from the file;
Well,
(1) Suggests a wrapper around the global info whose constructor takes an ifstream or file name string reference (hence, the file must exist before the constructor is called and it will still be there after the destructor is invoked);
(2) Suggests a global variable of the wrapper. You may, additionally, make sure that that is the only instance of this wrapper, in which case you need to make it a singleton as was suggested. Then again, you may not need this (you may be okay with having multiple copies of the same info, as long as it is read-only info!).
(3) Suggests a const getter from the wrapper. So, a sample may look like this:
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>//for EXIT_FAILURE
using namespace std;
class GlobalsFromFiles
{
public:
GlobalsFromFiles(const string& file_name)
{
//...process file:
std::ifstream ginfo_file(file_name.c_str());
if( !ginfo_file )
{
//throw SomeException(some_message);//not recommended to throw from constructors
//(definitely *NOT* from destructors)
//but you can... the problem would be: where do you place the catcher?
//so better just display an error message and exit
cerr<<"Uh-oh...file "<<file_name<<" not found"<<endl;
exit(EXIT_FAILURE);
}
//...read data...
ginfo_file>>gravity_;
//...
}
double g_(void) const
{
return gravity_;
}
private:
double gravity_;
};
GlobalsFromFiles Gs("globals.dat");
int main(void)
{
cout<<Gs.g_()<<endl;
return 0;
}
Globals aren't evil
Had to get that off my chest first :)
I'd stick the constants into a struct, and make a global instance of that:
struct Constants
{
double g;
// ...
};
extern Constants C = { ... };
double Grav(double m1, double m2, double r) { return C.g * m1 * m2 / (r*r); }
(Short names are ok, too, all scientists and engineers do that.....)
I've used the fact that local variables (i.e. members, parameters, function-locals, ..) take precedence over the global in a few cases as "apects for the poor":
You could easily change the method to
double Grav(double m1, double m2, double r, Constants const & C = ::C)
{ return C.g * m1 * m2 / (r*r); } // same code!
You could create an
struct AlternateUniverse
{
Constants C;
AlternateUniverse()
{
PostulateWildly(C); // initialize C to better values
double Grav(double m1, double m2, double r) { /* same code! */ }
}
}
The idea is to write code with least overhead in the default case, and preserving the implementation even if the universal constants should change.
Call Scope vs. Source Scope
Alternatively, if you/your devs are more into procedural rather thsn OO style, you could use call scope instead of source scope, with a global stack of values, roughly:
std::deque<Constants> g_constants;
void InAnAlternateUniverse()
{
PostulateWildly(C); //
g_constants.push_front(C);
CalculateCoreTemp();
g_constants.pop_front();
}
void CalculateCoreTemp()
{
Constants const & C= g_constants.front();
// ...
}
Everything in the call tree gets to use the "most current" constants. OYu can call the same tree of coutines - no matter how deeply nested - with an alternate set of constants. Of course it should be encapsulated better, made exception safe, and for multithreading you need thread local storage (so each thread gets it's own "stack")
Calculation vs. User Interface
We approach your original problem differently: All internal representation, all persistent data uses SI base units. Conversion takes place at input and output (e.g. even though the typical size is millimeter, it's always stored as meter).
I can't really compare, but worksd very well for us.
Dimensional Analysis
Other replies have at least hinted at Dimensional Analysis, such as the respective Boost Library. It can enforce dimensional correctness, and can automate the input / output conversions.