Public variables of class not being preserved when altered in function c++ - c++

I've found a question sorta similar to this one, though put in a more complex way than I think I require (received a -2 for question score). Hopefully this will be easier to follow.
The general gist of things is the two classes involved are GUI and Player (I've had the same problem elsewhere with other classes, but if I can understand why this one isn't working, it should apply to the rest).
GUI includes "Player.h". The class Player has a public boolean variable 'hasBall'; When a 'Player' is passed into a function Pass() and the boolean value changed, it seems that it is only a temp object thus isn't updating the object being passed itself. See code below:
This works fine, boolean values for Plyr1A and Plyr2A (defined in Gui.h) are changed and preserved
Plyr1A.hasBall = false;
Plyr2A.hasBall = true;
However boolean values for Plyr1A and Plyr2A remain the same with this.
Pass(Plyr1A,Plyr2A); //Boolean values for Plyr1A and Plyr2A remain the same with this.
void GUI::Pass(Player passer, Player receiver) {
passer.hasBall = false;
receiver.hasBall = true;
}
If anyone could explain to me why this occurs I'd be rather thankful! If there is any extra information needed please let me know.
Cheers :)

Your function makes a copy of the arguments (they are passed by value), then changes the copy, not the "original" objects(in the body of the function).
You should change it to take pointers or references, for example:
//-------------------v---------------v <---these are references
void GUI::Pass(Player& passer, Player& receiver) {
Of course, you should change the declaration, too.

Use references to pass your objects.

Consider this function:
void someFunction (int j)
{
j = 8;
}
And say we call it like this:
someFunction (3);
Are you thinking the assignment in someFunction somehow makes that 3 become an 8? Your expectation makes no sense. Without some kind of special arrangement, it cannot be that an assignment inside a function changes values in the caller.

Related

what /can/ you return from a function .. and expect it to be alive at arrival?

Once again I got cought on expecting a function to return a proper value and then be disapointed .. getting odd behavior and misleading debug-information instead.
It's fairly well known, that you cannot return a local variable from a function and expect it to arrive as you would expect. Testing
int i=2;
int k=4;
return make_pair<int,int>(i*i,k*k);
Does indeed return something respectable. But using more elaborate objects than simple types seems to catch me every time.
So, is there any formality that I can use for discriminating on what can and what cannot be returned safely from a function?
----------- added on edit: ------------
Here is the example that does not work, taken brutally out of context.
Problem-context is a (to be GUI) tree of rectangles for the screen.
Class node inherits from a base (rectangle) containing 3 pointers to plain types (again, used to make values stick) .. the base uses new in constructor
pair<node,node> node_handler::split( vector<node>::iterator& this_node, double ratio, bool as_horizontal ){
//this_node becomes parents to the split-twins
this_node->my_ratio=ratio;
double firstW, firstH;
double secW, secH;
glm::dvec2 afirst, asecond;
if(as_horizontal ){
firstW = *this_node->plWidth*LETTER_PIXEL_WIDTH;
firstH = *this_node->plHeight*LINE_PIXEL_HEIGHT*ratio;
afirst = *this_node->pPoint;
secW = firstW;
secH = LINE_PIXEL_HEIGHT*(*this_node->plHeight)*(1.0d-ratio);
asecond= afirst+glm::dvec2(0.0d, firstH);
}
else{
firstW = ratio*(*this_node->plWidth)*LETTER_PIXEL_WIDTH;
firstH = *this_node->plHeight*LINE_PIXEL_HEIGHT;
afirst = *this_node->pPoint;
secW = (1.0d*ratio)*(*this_node->plWidth)*LETTER_PIXEL_WIDTH;
secH = firstH;
asecond= afirst+glm::dvec2(firstW,0.0d);
}
return make_pair<node,node>( node(afirst ,firstW, firstH) , node(asecond ,secW, secH) ) ;
}
Technically, you can return anything from a function.
Now when you return a pointer or a reference to something that is only local, then you have a problem.
Solutions:
Return copies (OK with copy elision anyway)
Return shared_ptr<>/unique-ptr<> for something that must not be copied.
Return only basic types and pass to the function a reference to an object that might be modified.
Do not create something in the function that needs to be manually destroyed layer (say, a pointer created with new).
It's dawning on me, that classes containing pointer-members reasonably has to have custom copy/assignment operators. I never got to grips with the "rho" variable referred to in the books I read at the time ... "right_hand_object" it must be! That's my epiphany. It was following the business of the constructors and your talk of copyable objects that squeezed this old rho-problem of mine.
I'm sorry for having spread my frustration on you.

Creating and freeing a temporary dummy variable in C++

I'm using the Qt framework to create a ui for my business logic.
The class responsible for building the ui provides several methods which, step by step, initialize the ui elements, layout them, group them and, finally, format (i.e. void MyUi::init3_formatUiElements()) them.
Naturally, some ui elements need numerous layout settings set, so this method might look like
void MyUi::init3_formatUiElements() {
_spinBox_distance->setMinimum(0.0);
_spinBox_distance->setMaximum(10.0);
_spinBox_distance->setSingleStep(0.5);
_spinBox_distance->setSuffix(" meters");
//...
//same for other widgets
return;
}
Objects like QDoubleSpinBox* _spinBox_distance are member fields of the MyUi class.
I would like to have a "temporary alias" for _spinBox_distance, in that the above method body simplifies to
void MyUi::init3_formatUiElements() {
//create alias x for _spinBox_distance here
x->setMinimum(0.0);
x->setMaximum(10.0);
x->setSingleStep(0.5);
x->setSuffix(" meters");
//...
//free alias x here
//same for other widgets: create alias x for next widget
//...
//free alias x here
return;
}
This would speed up the typing process and would make code fragments more copy/paste-able, especially for ui elements of a similar type.
Apart from scoping each block in curly braces
{ QDoubleSpinBox*& x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ QLabel*& x = _label_someOtherWidget;
//...
}
is there an elegant way to achieve this?
I tried the above syntax without scoping, but destructing x then of course leads to destruction of the underlying widget.
Maybe
QDoubleSpinBox** x = new QDoubleSpinBox*;
x = &_spinBox_distance;
(*x)->setMinimum(0.0);
//...
delete x;
but that doesn't make things much more type-easy (three extra lines, pointers to pointers, (*x))... :D
EDIT: This one does not work as after delete x, can't be redeclared another type.
What about using a macro ?
#define Set(argument) _spinBox_distance->set##argument
and
Set(Minimum(0.0));
Set(Maximum(10.0));
Set(SingleStep(0.5));
Set(Suffix(" meters"));
Or
#define Set(Argument, Value) _spinBox_distance->set##argument(Value)
Set(Minimum, 0.0);
Set(Maximum, 10.0);
Set(SingleStep, 0.5);
Set(Suffix, " meters");
Collecting the fundamental conceptual thoughts about the problem in question from the comments section, I may post the syntactical/technical answer to the question. This approach, without a doubt, should not be chosen in any kind of "complex" situation (or rather not at all).
bad coding style:
same name for different things
name which doesn't tell you anything about the object
move repeated code to dedicated functions, which...
may specialize on several ui types
are template functions
...
in case of Qt: Use Qt Designer.
...
{ auto x = _spinBox_distance;
x->setMinimum(0.0);
//...
}
{ auto x = _label_someOtherWidget;
//...
}
will do the trick.
I think your code looks fine as it is, I find it much more useful to have the code be easy to read/understand than it is to have the code be easy to write. Remember that you write the code once, then have to read it many times afterwards.
In cases like this I make it easier to write with good old (and oft blamed for mistakes) copy and paste. Grab _spinBox_distance->set and just paste, finish the line, paste, finish the line, etc...
If, however, you find yourself writing those 4 setters in a row over and over again, then put them in 1 function that takes in the 4 parameters.
void SetParameters(QDoubleSpinBox* spinBox_distance, double min, double max, double step, std::string suffix)
{
//the setters
}

Using functions from classes

I am learning C++ and very new at using classes, and I am getting very confused in trying to use them. I am trying to convert my existing code (which used structs) so that it uses classes - so while I know what I am trying to do I don't know if I'm doing it correctly.
I was told that when using functions from the class, I first need to instantiate an object of the class. So what I have tried (a snippet) in my main function is:
int main()// line 1
{
string message_fr_client = "test"; //line2
msgInfo message_processed; //line 3
message_processed.incMsgClass(message_fr_client); //line 4
if (!message_processed.priority_check(qos_levels, message_processed)) //line 5
cout << "failure: priority level out of bounds\n"; //line 6
return 0; //line 7
}
Could you help me clarify if my following assumptions are correct? The compiler is not showing any error and so I don't know if it is error-free, or if there are ones lurking beneath.
At line 4, is the function incMsgClass being performed on the string message_fr_client and returning the resultant (and modified) message_processed?
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/*arguments*/)?
I haven't included the body of the functions because I know they work - I would just like to find out how the class functions interact. Please let me know if I can be clearer - just trying to clear up some confusion here.
Here is my class:
#ifndef clientMsgHandling_H
#define clientMsgHandling_H
#include <list>
#include <map>
#include <queue>
class msgInfo
{
public:
msgInfo();
msgInfo(int, int, int, std::string, std::list<int>);
/*classifying message*/
msgInfo incMsgClass(std::string original_msg);
/*message error checks*/
bool priority_check(int syst_priority, msgInfo msg); //check that message is within qos levels
bool route_check(std::map<std::pair<int, int>, int> route_table, msgInfo msg); //check that route exists
void getPath(msgInfo msg, std::map<std::pair<int, int>, int> route_info, int max_hop);
private:
int source_id;
int dest_id;
int priority;
std::string payload;
std::list<int> nodePath;
};
#endif
While it may compile (and even run), there are a few oddities with the code as shown:-
First off, class methods know which object they are operating on - so your priority_check and route_check methods probably don't need msgInfo as a parameter.,
for example, your old non-class function might be like this
bool priority_check(int p, msgInfo msg)
{
return msg.priority < p;
}
But the new one should look like this:
bool msgInfo::priority_check(int p)
{
return priority < p;
}
Also, incMsgClass is a bit odd, as it's a non-static class method that returns a msgInfo object. It's difficult to tell without understanding what it's supposed to do, but it seems possible that this function should actually be a constructor, rather than a regular method.
One other thing is that you're currently passing a msgInfo by value to those methods. So if the method needed to modify the passed msgInfo, it would not have any effect. It's generally better to pass objects by reference or const reference to other methods. So, back to the previous non-method example, it should really be this.
bool priority_check(int p, const msgInfo &msg)
...
But, as I said, you probably don't need the msgInfo parameters anyway.
At line 4, is the function incMsgClass being performed on the string message_fr_client
Yes
and returning the resultant (and modified) message_processed?
Whatever it's returning, you're ignoring the return value. It can modify the object itself, yes, because the function is not const.
At line 5, the function priority_check is being performed on the message_processed and returning a boolean?
Yes
In my class definition, I have a function getPath that is meant to modify the value of nodePath - is it just a matter of using message_processed.getPath(/arguments/)?
If a member function is intended to modify one of the class members, it's just a matter of not marking that function const
Hard to tell without implementation-details, but here we go:
I. You are passing a std::string as value (C++ is call-by-value by default), so you get a copy of the std::string in your method. If you want to work on the object you passed and manipulate it, use a reference on the object, like
msgInfo incMsgClass(std::string& original_msg); // notice the ampersand
then you can change your signature to
void incMsgClass(std::string& original_msg);
as you don't need to return the std::string you passed.
II. Yes, at least according to your signature
III. Can see a node_path only as a member.
For all your questions, see C++-FAQ.
Your basic assumptions are correct.
message_processed.incMsgClass(message_fr_client); //line 4
This line is not correct. The function you call returns msgInfo which is simply dropped. You should assign it to something. But it is not as it is usually done. You should make it a constructor of msgInfo, like
class msgInfo
{
public:
msgInfo(std::string original_msg);
...
}
Then you could call it like this
msgInfo message_processed(message_fr_client);
That line would create a msgInfo that is already properly initialized.
There is another pattern for creating class instances - static creating function. In your case you could mark incMsgClass static and then call it like
msgInfo message_processed = msgInfo.incMsgClass(message_fr_client);
I seriously doubt you need this pattern here, so I'd advise to move to constructor.
As of other functions, I see no problems there. Just note that all member functions not marked as const can modify the object they are called on. So, you don't need to pass this object explicitly. For functions a pointer to the object they are called on is available by name this. Also the functions can access all class variables as if these variables are global for normal (non-member) functions.

Creating a vector in a method and setting it to a variable

OK so I an new to C++ and am fairly sure this should be a simple question if I can ask it right. Basically this is what I need to work:
printInfoFromVector(this->mycontroller.createVector)
This is the actual code I have:
vector<GasStation>& highPrices = this->myController.findHighestPrice();
this->findPrice(highPrices);
vector<GasStation>& findHighestPrice(){
The problem that I am having is that I can not get they types of highPrices and findHighestPrice() to match. Im fairly sure the problem is because I am passing by ref but I pretty sure that the right way to do it.
Can anyone tell me the correct way to write the assignment statement and the method head so that the types match?
If findHighestPrice is computing a new vector, then you should not return a reference, but an actual vector. Thus you would have:
vector<GasStation> findHighestPrice() { ... }
vector<GasStation> highPrices = this->myController.findHighestPrice();
For example, if you defined findHighestPrice as
vector<GasStation>& findHighestPrice() {
vector<GasStation> stations;
// ...
return stations;
}
then stations will be deallocated when the function returns and highPrices will be undefined.

confusion about void and what it means.

I am very new to programming and am confused about what void does, I know that when you put void in front of a function it means that "it returns nothing" but if the function returns nothing then what is the point of writing the function?? Anyway, I got this question on my homework and am trying to answer it but need some help with the general concept along with it. any help would be great, and please try to avoid technical lingo, I'm a serious newb here.
What does this function accomplish?
void add2numbers(double a, double b)
{
double sum;
sum = a + b;
}
void ReturnsNothing()
{
cout << "Hello!";
}
As you can see, this function returns nothing, but that doesn't mean the function does nothing.
A function is nothing more than a refactoring of the code to put commonly-used routines together. If I'm printing "Hello" often, I put the code that prints "Hello" in a function. If I'm calculating the sum of two numbers, I'll put the code to do that and return the result in a function. It's all about what you want.
There are loads of reasons to have void functions, some of these are having 'non pure' side effects:
int i=9;
void f() {
++i;
}
In this case i could be global or a class data member.
The other is observable effects
void f() {
std::cout <<"hello world" << std::endl;
}
A void function may act on a reference or pointer value.
void f(int& i) {
++i;
}
It could also throw, although don't do this for flow control.
void f() {
while(is_not_broke()) {
//...
}
throw std::exception(); //it broke
}
The purpose of a void function is to achieve a side effect (e.g., modify a reference parameter or a global variable, perform system calls such as I/O, etc.), not return a value.
The use of the term function in the context of C/C++ is rather confusing, because it disagrees wiht the mathematical concept of a function as "something returning a value". What C/C++ calls functions returning void corresponds to the concept of a procedure in other languages.
The major difference between a function and a procedure is that a function call is an expression, while a procedure call is a statement While functions are invoked for their return value, procedures are invoked for their side effects (such as producing output, changing state, and so on).
A function with void return value can be useful for its side effects. For example consider the standard library function exit:
void exit(int status)
This function doesn't return any value to you, but it's still useful for its side-effect of terminating the process.
You are on the right lines - the function doesn't accomplish anything, because it calculates something but that something then gets thrown away.
Functions returning void can be useful because they can have "side effects". This means something happens that isn't an input or output of the function. For example it could write to a file, or send an email.
Function is a bit of a missnomer in this case; perhaps calling it a method is better. You can call a method on an object to change its state, i.e. the values of it's fields (or properties). So you might have an object with properites for x and y coordinates and a method called Move which takes parameters xDelta and yDelta.
Calling Move with 2, 3 will cause 2 to be added to your X property and 3 to be added to your Y property. So the state of the object has changed and it wouldn't have made musch sense for Move to have returned a value.
That function achieves nothing - but if you had written
void add2numbers(double a, double b, double &sum)
{
sum = a + b;
}
It would give you the sum, whether it's easier to return a value or use a parameter depends on the function
Typically you would use a parameter if there are multiple results but suppose you had a maths routine where an answer might not be possible.
bool sqrt(double value, double &answer)
{
if value < 0.0 ) {
return false;
} else {
answer = real_sqrt_function(value);
return true;
}
}
I currently use a visualization library called VTK. I normally write void functions to update some part of the graphics that are displayed to the screen. I also use void functions to handle GUI interaction within Qt. For example, if you click a button, some text gets updated on the GUI.
You're completely right: calculating a function that returns nothing is meaningless – if you're talking about mathematical functions. But like with many mathematical concepts, "functions" are in many programming languages only related to mathematical functions, but behave more or less subtly different.
I believe it's good to explain it with a language that does not get it wrong: one such language is Haskell. That's a purely functional language which means a Haskell function is also a mathematical function. Indeed you can write Haskell functions much more mathematical-styled, e.g.
my_tan(x) = sin(x)/cos(x) -- or (preferred): tan' x = sin x / cos x
than in C++
double my_tan(double x) { return sin(x)/cos(x); }
However, in computer programs you don't just want to calculate functions, do you? You also want to get stuff done, like displaying something on your screen, sending data over the network, reading values from sensors etc.. In Haskell, things like these are well separated from pure functions, they all act in the so-called IO monad. For instance, the function putStrLn, which prints a line of characters, has type String -> IO(). Meaning, it takes a String as its argument and returns an IO action which prints out that string when invoked from the main function, and nothing else (the () parens are roughly what's void in C++).
This way of doing IO has many benefits, but most programming languages are more sloppy: they allow all functions to do IO, and also to change the internal state of your program. So in C++, you could simply have a function void putStrLn(std::string), which also "returns" an IO action that prints the string and nothing else, but does not explicitly tell you so. The benefit is that you don't need to tie multiple knots in your brain when thinking about what the IO monad actually is (it's rather roundabout). Also, many algorithms can be implemented to run faster if you have the ability to actually tell the machine "do this sequence of processes, now!" rather than just asking for the result of some computation in the IO monad.