getting user input into a class statically in C++ - c++

I have a large simulation written in C++. The main working unit for the simulation is a class that represents neurons. To do its calculations, each instance of the neuron class needs access to the temperature. Each simulation uses tens of thousands of instances of the neuron class and the temperature is the same value for each neuron. For this reason, I would rather not have it be stored as regular member data, so each instance of the neuron class doesn't have to take up memory storing its own copy. I would ideally store it as a static member variable (or, as a last resort, a global variable). However, I need the temperature to be determined at run-time as user input. Is there any simple way to give the neruon class access to this variable in the manner of static member data?

Just because a variable is static, doesn't mean that it also needs to be const. See the below code.
#include <cassert>
struct X {
int member;
static int static_var;
};
int X::static_var;
int main() {
X x;
x.member = 1;
x.static_var = 2;
X y;
y.member = 3;
y.static_var = 4;
X::static_var = 5;
assert(x.static_var == y.static_var);
assert(&x.static_var == &y.static_var);
}

Just provide a static member function, which you can call at runtime and set the temperature member.
Alternatively, You could just make the static member public and set it directly, As a personal choice I prefer doing it through member function though.
class Neuron
{
public:
static void setTemperature(int i)
{
mTemp = i;
}
private:
static int mTemp;
};
int Neuron::mTemp = 0;
int main()
{
//Get Temperature at run-time
Neuron::setTemperature(10);
return 0;
}

I see something like this as a good candidate for a global. What if you add something to your simulation that also uses the temperature?
Since a global variable could be modified by anyone at any time, I suppose the best solution IMO is to have a globally-scoped (standard) function like getTemperature(). Then any object could call it at any time. Putting it in its own C file and marking it static makes it only accessible through a mechanism you choose.
Also alternatively, if one doesn't like that, would be to create a static Globalsor SimulationInputs class, with getters for things just like temperature.

Singleton, global, static data, oh my!
The data model for C++ allows us to have global access to data, and to restrict the number of instances of that data, through various mechanisms and hacks.
Just because we can, though, doesn't mean we should. And just because you have a design where it could be a solution, doesn't mean you should choose it.
Normally, you have classes which manage their own data. If an object needs some data which it doesn't manage, you pass it as a parameter.
So, pass the temperature as a parameter. Explicit is better than implicit.
You mentioned that you have a class representing Neurons. I assume you meant Neuron, but it would also be good to have a Neurons class which keeps them all together. It can have a temperature which it applies to all the Neuron calculations.

Related

making static variables in member functions independent for each instance

Given the class:
class A {
Public:
void foo() {
static int i;
i++;
}
};
How would you change it to prevent i from changing between instances following this example:
A o1, o2, o3;
o1.foo(); // i = 1
o2.foo(); // i = 1
o3.foo(); // i = 1
o1.foo(); // i = 2
i.e. allocate memory for i on every instance.
EDIT:
Yes, you can add i as an instance variable, but what if you need these counters in various (independent) functions ? I am looking to limit the scope of the variable only to the function ("in member functions"). It would seem awkward to add variables such as i, c, counter, counter_2 to the class if you need various counters, would it not ?
class A
{
public:
int i = 0;
void foo(){
++i;
}
};
is the normal way: i is now a member variable of the class. Clearly you don't want to use static.
In circumstances where declaring data members become costly(need for sparse members that are not used so often), An instance indepent collection - normally an associative one - may come in handy. Knowing nothing more about the OP's intention, std::map family of classes can be used as first speculation. We need to have one counter per visited object in A::foo, but not for unvisited instances(i.e. A instances not calling A::foo). This was the the simplest first solution I came up with:
void A::foo(){
static std::map<A*,std::size_t> i;
++i[this];
//...
};
Upon call to std::map::operator[] on an object not in the map, the associated value is default constructed in a memory location already zeroed by the allocator( in short words 1st-timers are automatically initialized to 0).

Call function once across multiple instances of a class

I have been looking around for a while now and can't seem to find an answer to this.
So, if I have several instances of a class, how can I call a function only once from all instances of that class?
For example, if I have a function called myFunc() within a class called myClass and two instances of that class called class1 and class2, then
class1.myFunc() should return 1,
class2.myFunc() should return 0, and
class1.myFunc() should return 0.
How would I do this?
class myClass{
public:
myClass(){}
int myFunc(){
if (myFuncHasBeenCalled){
return 0;
}
else{
return 1;
}
}
}
myClass class1;
myClass class2;
class1.myFunc(); //would output 1
class2.myFunc(); //would output 0
class1.myFunc(); //would output 0
You can achieve that by
introducing a class variable, using static keyword for it in class declaration
define the class variable in a (separate) code file, with initialisation
check it inside the function, if 0 output 1 else 0
increase (or set to non-zero) afterwards
be careful, using synchronisation mechanisms, in case the calls might be from different contexts/threads/tasks/processes (whatever is applicable in your environment)
(If you show your attempts with static variables and explain the problems you had, this could become more detailed.)
You have several options available: the idea is that you need to have some value that can be accessed independently of the instances of the class. static is the way to do this in all cases (except when it's not).
Option one is best option -- static variable in member functions
The approach I would recommend is using a static variable in the member function; this avoids polluting the class itself and makes it easier for you to maintain a consistent ABI as well as a consistent API, across updates. It is very easy to reason about your code as you're not allowing anything else to access the variable.
Example:
struct S {
int F() const {
static int n = 1;
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
Option two is bad option -- static variable in class
An alternative, which seems to be popular, is to keep a static member variable. This allows you do to the same thing as the previous example, but makes it harder to maintain the API and the ABI across upgrades. It also makes it harder to reason about your code and makes it easier to introduce bugs -- a static member variable is not much different from a global variable.
Example:
struct S {
static int n;
int F() const {
if (n == 1) {
n = 0;
return 1;
}
return n;
}
};
int S::n = 1;
Option three is worst option -- global variables
The worst alternative is to use a global variable. I'm not going to give you an example of this -- don't do it. If you must do it anyway (you don't), declare your variables in an anonymous namespace in your .cpp file.
namespace {
int n = 0
}
Options four -- good option
Another approach is to use a static member function. This functions is fully independent of all instance of the class. The only difference in the implementation is that you add static to the function declaration -- otherwise, you can use the first two options. This won't be possible in all situations though.
Caveats and other notes
If you need to use the variable to communicate state between two functions, you have to use one of the global options and cannot use a static variable in a member function.
In all cases, if you're not modifying the instance, you should mark your functions const.
You should really use std::atomic variables
You should use some sort of mechanism that guarantees that your code is threadsafe.

Static member function with set parameters needs access to non-static data members

I have a static function that needs to access data members of a class. The function can be a member, non member or friend function of the class, but it must be static and it cannot take any arguments. So I cannot pass the data members to it as a parameter nor can I pass the object itself to it.
#include "sundials.h"
#include "CVode.h"
class nBody
{
private:
double masses[];
double** paths;
static int accelerator();
//...
public:
//...
void runODE();
};
int nBody::accelerator()
{
// code that needs to know the values stored in masses[]
}
void nBody::runODE()
{
//...
ODEsetAccelerator(accelerator); //require accelerator to be static int
//with specific parameters
// run the ODE
//record trajectories in paths[][]
}
accelerator is fed to a separate ODE solver which requires accelerator to be type static int and take specified arguments, So I can't pass the masses into accelerator because it will be called by the ODE and not main
is there any way I could make the accelerator function know what the value of masses? I don't care how indirect it is.
Let me start off saying your design is broken. A static method that needs to access non-static members of a class and can't receive parameters?
That aside, sure you can. You can access a global object from inside the static method, that's set to the current object you're trying to manipulate:
extern nBody* currentBody;
//........
int nBody::accelerator()
{
//access currentBody
//since this is a member, you have access to other private members
}
//....
nBody someBody;
currentBody = &someBody;
nBody::accelerator();
If this is the "sundials" and "CVode" that show up on a quick web search:
Use the relevant nBody* as the user_data parameter.
It's described in the documentation of the user function (page 55).
If not, please disregard this answer.
Given your constraints, a horrible solution would be to have a static variable in the class called something like currentNBody of type nBody * and set this to the appropriate instance before running the ODE solver.
You are correctly identifying this as a global variable. Of course this will fail utterly if you're doing anything multi-threaded.
This is what i think you are talking about:
Some processing is creating nBody objects with masses.
Some other processing needs to 'accelerate' them.
You need a way essentially to 'register' nBody objects with the 'acceleration process'.
That could be a static method on the AccelerationProcess object or via some callback via RMI, etc.
It is the accelerator process that holds in its state the nBody object references and thus no reason to have a static method on nBody. That is assuming the objects all live in the same memory space - otherwise things get more complicated.

Accessing data from a callback

I have some code and data, both currently encapsulated within a struct, which in turn is within a namespace. I'm trying to integrate an external library, which makes use of old-fashioned callbacks. I need access to my data within the context of the callback, but the callback API provides no means of adding personalized parameters.
The only way I know to circumvent this is to either add a global pointer to my struct, so that the callback knows where to find the data, or use a tangle of boost classes to create a fake function pointer from my struct for the callback to use. Both options feel more like hacking around OOP limitations than actual solutions.
So, I'm debating whether or not to ditch the struct completely, and convert it to free-standing code and data. Essentially, the data would become global (or more likely, wrapped within a global struct), but would be within the confines of it's namespace.
Justification for making the data "global":
The code has a single purpose in the program, and always uses the same set of data for the life of the program. The data is never allocated or freed.
This code and data are never instanced. There never are and never will be multiple copies.
I have no love for OOP (I use C++ because it is the best tool for the job), so I don't feel the need to keep it encapsulated on principle alone.
However, there is one downside that I would like to avoid:
Even though the data is in a separate namespace (and ignoring the fact that I am the only person writing this program), there is nothing to prevent other parts of the program from accessing this data. And if it were to happen, I will have no easy way to track it.
The only idea I've had so far is to wrap the global data within an unnamed namespace. This should, for all intents and purposes, make it invisible to the rest of the code base, and remove the most common reason for not using globals. However, it also means that the code that does need to access it must all be contained within a single file, which could become a pain to work with if that file gets large.
Is there another option I'm not thinking of, or is this as good as it gets?
You could just some templated static functions to give you a data pointer, though you would have to specify these at compile time:
#include <iostream>
using namespace std;
template <class Data, int ID>
struct ext_library_context
{
static Data data;
static void callback()
{
// callback code, using data
cout << data << endl;
}
};
template <class Data, int ID>
Data ext_library_context<Data, ID>::data;
void ext_library_call(void callback())
{
callback();
}
int main()
{
int d1 = 1;
ext_library_context<int, 1>::data = d1;
int d2 = 2;
ext_library_context<int, 2>::data = d2;
ext_library_call(ext_library_context<int, 1>::callback);
ext_library_call(ext_library_context<int, 2>::callback);
}
As long as you use a unique Data/ID template parameter combination for each call, you shouldn't have any issues.
As for protecting your global state from unintended use, you could wrap it in a class, mark members as private to taste, and declare the callback functions as friends.
Put your data in a class and instantiate this class static-ally:
class MyClass {
private:
Data data; // variables which you avoid declaring globally
public:
void real_callback() {
do_something(data);
}
};
void callback() {
static MyClass my_class; // here is the trick.
my_class.real_callback();
// Or you can instantiate it on heap
// static auto my_class = new MyClass;
// my_class->real_callback();
}
int main() {
old_function_wanting_a_callback(callback);
}

How to call-by-reference a variable of one class from another in C++

I have a class, let's call it class A, that is performing a calculation which returns a value of int value, and another class in my system, class B needs to use int value for further calculations. My plan is to use a third class, class C, where the variable will be defined, to pass the variable between A and B, with these two just working from references to the int value in class C. My problem is I don't know how to reference a variable in another class without first instantiating some class or another, with the ensuing construction potentially overwriting int value.
Update: The code below outlines what I'm trying to achieve. I'm am trying to have variable
class A
{
public:
void calculation1()
};
void A::calculation1()
{
value = 10;
}
class B
{
public:
void calculation2();
};
void B::calculation2()
{
for (int count = 0; count < value; count ++)
{
// Do stuff here
}
}
class C
{
int value;
}
I believe you're not going in the right direction here. If I rephrase your problem description in pseudo-code, I get something like :
// The second calculation result depends on the result of the first one, so we
// provide it as a parameter.
int firstValue = calculationA();
int secondValue = calculationB(firstValue);
This is perfectly valid in itself : you just have to implement two free functions calculationA and calculationB and there is no need for classes of anything like it. Now, if you really want to put classes around this, you can.
What you need to understand is that classes interaction are a consequence of their respective responsibilities, not the opposite. For example, if the result of calculation1 has absolutely no utility beside being fed to calculation2, maybe the two functions shouldn't belong to different classes. Identify the responsibilities, try to express them as classes, and the interaction will appear naturally.
Why not just have a set function in class B, where you can set the value to what the calculation in A returns?