Passing variable from function A to main and back to another - c++

I have the following example
int main() {
...
}
void parameterList() {
...
}
void myMethodA() {
...
}
void myMethodB() {
...
}
void myMethodC() {
...
}
I have read several StackOverflow posts on this subject and understand to pass a variable from myMethodA() to myMethodB(), I will need to call myMethodB() in myMethodA() with the variables. To illustrate
void parameterList() {
...
int someInteger = 45;
string someName = "John";
int otherInteger = 20;
myMethodB(someName, someIntegers);
myMethodC(otherInteger);
}
void myMethodB(string &someName, int &someInteger) {
...
string another_someName = someName;
int another_someInteger = someInteger;
...
}
void myMethodC(int &otherInteger) {
...
int another_someInteger_two = otherInteger;
...
}
parameterList() is a function where it contains multiple variables for multiple myMethod() functions. On initial program run, parameterList() will have to run first in main to get all the necessary variable. Ideally, the main function will obtain all these variables from parameterList() and pass it to myMethod() in main function. To illustrate
Step 1
main function will run parameterList()
Step 2
parameterList() process and have multiple variables meant for multiple myMethod()
Step 3
main function should have a variable that can "store" these variables in order to pass it to all the myMethod() for further processing
The main function will not run myMethodB() until it is told to do so and when the variables from myMethodA() is inside the main.
Any clarification on this is greatly appreciated. Thanks for taking your time!

You could also use a class to wrap data and also manage the lifetime of the objects.
class Context {
int someInteger;
string someName;
Context(int a, const string& b) :
someInteger(a),
someName(b)
{}
void myMethodA() {
/* do something with someInteger and someName */
}
void myMethodB() {
/* do something with the results from myMethodA */
}
};
int main() {
Context ctx{45, "John"};
ctx.myMethodA();
ctx.myMethodB();
}

Passing variable from function A to main and back to another
To pass a value out of a function, you can return it.
To pass a value into a function, you can use a parameter. Example:
int myMethodA() {
int someInteger = 45;
// ...
return someInteger;
}
int main()
{
int someInteger = myMethodA();
myMethodB(someInteger);
}
I don't think this will work if myMethodA() will need to return more than 1 variable
That's not a problem. While only one object can be returned, that object can be of a class type, and classes can contain more than one sub object. Example:
struct example {
int someInteger;
string someName;
};
example myMethodA();
void myMethodB(const example&);
If it makes sense for the structure of the program, the functions could potentially be made member functions of the class such as demonstrated in KamilCuk's answer.
Can the struct have array?
Yes. Class members can be arrays.
Is 'example myMethodA()', is that in the main function?
That is a declaration of a function that returns instance of example.
How should I return these variables in myMethodA() inside myMethodA() return?
Same way as you return other objects. With the return statement.

Related

global function and class reference

I want to send integer value in class to global function from main. How should I send it as a parameter,I am sending the parameters wrong
Tetris
{
private:
int num;
}
printBoard(Tetris &t);
int main()
{
Tetris tetris;
printBoard(board,tetris);
}
i want to send num , to printboard.
There are several problems with the shown code.
First, you're missing the class keyword when defining the class.
Second, the return type of the function is also missing.
Third, the function has only one parameter but you're passing two arguments.
i want to send num , to printboard
You can add a getter called getNum which you can use from inside your free function as shown below:
vvvvv------------->added this class keyword
class Tetris
{
private:
int num = 0; //don't forget to initialize
public:
//add a getter
int getNum() const
{
return num; //return a copy
}
};
vvvv----------------------->added return type as void
void printBoard(Tetris &t)
{
std::cout << t.getNum(); //use the getter
}
int main()
{
Tetris tetris;
printBoard(tetris);
}
Demo

How do I pass a function within a namespace as a non-namespace parameter?

I need to call a function when a button is pressed. The following function should take in the function to be called:
void ButtonLayer::LoadButton(void(*func)()) {
// do button loading stuff
// if button is clicked...
func();
}
This would work except for the fact that passing a function within a seperate namespace gives the following error:
argument of type "void(OtherLayer::*)()" is incompatiable with parameter of type "void(*)()"
I don't want to make every function I pass static to avoid this problem, so I need some way of converting a function within a namespace to be of type void(*). I have tried static casting but I'm unsure of the exact syntax as I'm new to C++
It seems that you want to pass a member function.
This example may help you.
class A {
public:
int i;
int fun(int j) {
return i + j;
};
};
void fun(int j, A ob, int (A::* p)(int)) {
std::cout << (ob.*p)(j);
}
void main() {
int (A:: * fp)(int); //declare fp as a function pointer in class A
fp = &A::fun; //init fp
A obj;
obj.i = 1;
fun(123, obj, fp);
}
Based on #Yksisarvinen and #MSalters comments, the solution was:
void ButtonLayer::LoadButton(std::function<void()>) {
// do button loading stuff
// if button is clicked...
func();
}
and then to call it:
LoadButton([this] { functionToCall; });

C++ global variable that can be changed only in one method, possible?

I'm looking for a way to have an int variable that persists value across method calls. From this perspective a class member will be good.
But I would like that int variable to be changed in only one particular method.
How do I make that?
I tough about
void MyClass::my_method(){
static int var = 0;
var++;
}
But, I would like var = 0; to be executed only the first time.
void my_method(){
static int var;
var++;
}
The problem here is, that
static int var;
is only visible in the local scope of my_method().
You can make it global just by definition of that variable outside of my_method():
int var;
void my_method() {
var++;
}
but var will be visible for everyone.
The better way is to encapsulate all of that into a class:
class MyClass {
public:
static void my_method() {
var++;
}
private:
static int var = 0;
};
You can use the following key access pattern:
struct Foo {
void fun1();
void fun2();
static class Var {
friend void Foo::fun1();
int i = 0;
public:
int value() const { return i; }
} var;
};
Foo::Var Foo::var;
void Foo::fun1() { var.i = 42; }
void Foo::fun2() {
// var.i = 42; // this will generate compile error cause fun2 doesn't have to var
}
Live Demo
This way only the member functions of Foo that are declared friends in wrapper class Var can change its private member variables (e.g., var.i).
var is just locally, if you want that to be 0 the first time the function returns make it initialized to -1 or if 0 is just right you are ok. As is var is only visible inside my_method so if you want that to be visible to all the class you have to put it outside and use only my_method to modify the value.
I don't have enough rep to comment yet, But you should note that Static is not equal to Constant.
Static variables maintain their value for ALL instances of a class, whereas Constant variables can have different values for each instance (object) of a class.
See this question for a more in-depth explanation.
What is the difference between a static and const variable?
To answer your question directly, you cannot have a true "Global" vairable that is only editable from one class. Instead, you should consider πάντα ῥεῖ 's answer OR wait to declare the constant until after you know the value you would like to assign to it. For instance, I want to store X+10 to a constant variable Y
int x = 5 //create variable
//Do whatever you need to do to get the value
function myFunction(){
x = x + 10;
}
const int y = x; //now Y = 15 and cannot be changed.

Is it possible to access a variable in a sketch from a class (Arduino)?

Say I want to get a value of a variable in a sketch from a class I wrote like
sketch
int device;
void setUp() {
device = 1;
}
And I have a class
SomeClass.cpp
void Device::checkTimedEvent() {
someDevice = device; //variable from sketch
}
I know it's possible to access members from another class where I can include the class and use the :: scope operator but not sure how the sketch relates to classes.
thanks
It appears that the usual C/C++ "extern" syntax works in Arduino as if the sketch file were a .cpp file:
Sketch:
int device = 123;
SomeClass.cpp:
extern int device;
void SomeClass::checkTimedEvent() {
someDevice = device; // variable from sketch
// will display "123" (or current value of device)
// if serial output has been set up:
Serial.println("device: " + String(device));
}
You may need to worry about startup and initialization order, depending on the complexity of your project.
class Test
{
public:
int N = 0;
};
Test t;
int someNumber = t.N;
The best way to do this is to pass the value into the function as a parameter. Here's a simple example:
Class:
class Test
{
public:
void doSomething(int v);
private:
int myValue;
};
void Test::doSomething(int v)
{
myValue = v;
}
Sketch:
Test t;
int someNumber;
void setup()
{
someNumber = 27;
t.doSomething(someNumber);
}
The setup() function here passes global variable someNumber into the class's member function. Inside the member function, it stores its own copy of the number.
It's important to note that it has a completely independent copy of the number. If the global variable changes, you'd need to pass it in again.
As much as Bloomfiled's answer is correct using the the more accepted practice of employing Getter and Setter functions. Below demonstrates this along with making the attribute public and directly accessing it.
class Test
{
public:
void SetMyValue(int v);
int GetPublicValue();
int GetPrivateValue();
int myPublicValue;
private:
int myPrivateValue;
};
void Test::SetMyValue(int v)
{
myPublicValue = v;
myPrivateValue = v;
}
int Test::GetPublicValue()
{
return myPublicValue;
}
int Test::GetPrivateValue()
{
return myPrivateValue;
}
Test t;
int someNumber;
void setup()
{
someNumber = 27;
t.SetMyValue(someNumber); // set both private and public via Setter Function
t.myPublicValue = someNumber; // set public attribute directly.
someNumber = t.GetPublicValue(); // read via Getter
someNumber = t.GetPrivateValue();
someNumber = t.myPublicValue; // read attribute directly
}
void loop() {
// put your main code here, to run repeatedly:
}

Static function needing to deal with members of a C++ class

I have to make some kind of bridge between two pieces of software, but am facing an issue I don't know how to deal with. Hopefully someone will have interesting and (preferably) working suggestions.
Here is the background : I have a C++ software suite. I have to replace some function within a given class with another function, which is ok. The problem is that the new function calls another function which has to be static, but has to deal with members of the class. This is this second function which is making me mad.
If the function is not static I get the following error :
error: argument of type ‘void (MyClass::)(…)’ does not match ‘void (*)(…)’
If I set it to static I get either the following error :
error: cannot call member function ‘void
MyClass::MyFunction(const double *)’ without object
or
error: ‘this’ is unavailable for static member functions
depending on if I use or not the "this" keyword ("Function()" or "this->Function()").
And finally, the class object requires some arguments which I cannot pass to the static function (I cannot modify the static function prototype), which prevents me to create a new instance within the static function itself.
How would you deal with such a case with minimal rewriting ?
Edit : Ok, here is a simplified sample on what I have to do, hoping it is clear and correct :
// This function is called by another class on an instance of MyClass
MyClass::BigFunction()
{
…
// Call of a function from an external piece of code,
// which prototype I cannot change
XFunction(fcn, some more args);
…
}
// This function has to be static and I cannot change its prototype,
// for it to be passed to XFunction. XFunction makes iterations on it
// changing parameters (likelihood maximization) which do not appear
// on this sample
void MyClass::fcn(some args, typeN& result)
{
// doesn't work because fcn is static
result = SomeComputation();
// doesn't work, for the same reason
result = this->SomeComputation();
// doesn't work either, because MyClass has many parameters
// which have to be set
MyClass *tmp = new MyClass();
result = tmp->SomeComputation();
}
Pointers to non-static member functions are a bit tricky to deal with. The simplest workaround would just be to add an opaque pointer argument to your function which you can then cast as a pointer to 'this', then do what you need with it.
Here's a very simple example:
void doSomething(int (*callback)(void *usrPtr), void *usrPtr)
{
// Do stuff...
int value = callback(usrPtr);
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(myCallback, this);
}
private:
int value_;
static int myCallback(void *usrPtr)
{
MyClass *parent = static_cast<MyClass *>(usrPtr);
return parent->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
In this example myCallback() can access the private value_ through the opaque pointer.
If you want a more C++-like approach you could look into using Boost.Function and Boost.Bind which allow you to pass non-static member functions as callbacks:
void doSomething(boost::function<int ()> callback)
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
doSomething(boost::bind(&MyClass::myCallback, this));
}
private:
int value_;
int myCallback()
{
return value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
If you really can't change the function prototype you could use a global pointer, but that opens up all sorts of issues if you will ever have more than one instance of your class. It's just generally bad practice.
class MyClass;
static MyClass *myClass;
void doSomething(int (*callback)())
{
// Do stuff...
int value = callback();
cout << value << "\n";
}
class MyClass
{
public:
void things()
{
value_ = 42;
myClass = this;
doSomething(myCallback);
}
private:
int value_;
static int myCallback()
{
return myClass->value_;
}
};
int main()
{
MyClass object;
object.things();
return 0;
}
Following spencercw's suggestion below the initial question I tried the "static member variable that you set to point to this" solution (the global variable would have been tricky and dangerous within the context of the software suite).
Actually I figured out there was already something like this implemented in the code (which I didn't write) :
static void* currentObject;
So I just used it, as
((MyClass*)currentObject)->SomeComputation();
It does work, thanks !!!
non-reentrant and non-thread-safe way is to pass "this" address using global variable.
You can move the result = SomeComputation(); out of your static function and place it in BigFunction right before your call to the static function.