Pass by reference, child scope only? - c++

I have tried searching on this, since I bet there are questions like these already. However I only get topics about passing by reference in a global setting.
I was wondering about the following;
Variable scope is in this function only and will be cleaned when leaving the scope
void Class::DoSomething(){
String s = "localVariable";
cout << s;
}
If I would change the prior function in the following two functions. Would the scope be also only in the parent function and will the variable memory be freed or do I have to call free()?
void Class::DoSomethingParent(){
String s = "localVariable"; //Local scope only
//This function uses the reference of my variable s.
Class::DoSomethingChild(s);
//Does the prior function do anything special because of the reference,
//so I have to call free(s)?
//Or does the variable still gets freed after leaving the scope of this function?
}
void Class::DoSomethingChild(String& value){
cout << value;
}

Objects with an Automatic Storage Duration in C++ are essentially objects declared within a function block scope, that scope owns and controls the lifetime of such objects created therein. Example:
void function(){
....
String s = "Some Data";
someFuncByReference(s);
....
} //All objects of automatic storage duration owned by this scope are destroyed here...
Irrespective of whether you pass the object by reference or take the address of the object, and pass unto a function. The called function, someFuncByReference still doesn't control the lifetime of s, and should not destruct s1.
This applies to any "function", including, non member-functions, member-functions and function specializations produced by templates. Note that, this is not the same with data members of a class. The lifetimes of class data members are controlled by the constructor and destructor of that class.
1: However, if it does, it must create another one using placement-new.

Related

what is the scope of this variable in c++?

If i define a function like this
std::string& returnstring(std::istringstream &ist)
{
std::string temp;
std::getline(ist,temp);
return temp;
}
and if i use this temp which is passed by reference to another function like this
void displaystring(std::string &temp)
{
std::cout<<temp;
}
would the string temp still be in scope when i pass it by reference to displaystring function?
The scope of a variable is the scope where it is declared. std::string temp; is declared within the body of the function returnstring, therefore that function body is the scope of the variable. It is an automatic variable, and therefore its lifetime ends at the end of its scope and it is automatically destroyed.
The returned reference will be invalid (i.e. it is a dangling reference). If you attempt to access the non-existing object through the invalid reference, then the behaviour of the program will be undefined.
To fix the function, a simple solution is to return a value instead.
Nope since the temp variable is local to the returnstring function and once the code is out of the retuernstring function the temp variable is no longer valid.
If at all you want to send the reference and get the answer then better option is to send the argument by reference as below,
void copyLineAsString(std::istringstream &ist, std::string& tempString)
{
std::getline(ist,tempString);
return;
}
I have few other suggestions to your code for the good coding practice,
Never use the '&' for the return type / return a variable by reference. Use camel casing or _ separator for the function names(Ex returnString or return_string).
No. The scope of temp is limited to the block where it is declared. Because you declared it on stack (you didn't use the keyword new), the variable temp will be destroyed the moment you exit the function.
The only way to keep the variable would be to have the value of temp be copied to a variable outside the function. For example, this would work:
std::string returnstring(std::istringstream &ist)
{
std::string temp;
std::getline(ist,temp);
return temp;
}
Because the return value is a copy rather than a reference, you could then do
std::string returned_string = returnstring(ist);
And have the value of temp be copied into a newly declared variable that could be used for your displaystring function.
In general, I would avoid declaring variables inside a function that you will need outside the scope of the function. Instead, return by value whenever you are returning variables built inside of the function (not recommended for large arrays and objects, however).
this is the reference variable which refers to the current class object which has called it. it has scope only inside the class and the same as the lifetime of the object which called it.

if I return a class in my function, where does it store?

look at my code:
#include <iostream>
using namespace std;
class MyClass{
public:
char ch[50] = "abcd1234";
};
MyClass myFunction(){
MyClass myClass;
return myClass;
}
int main()
{
cout<<myFunction().ch;
return 0;
}
i can't understand where my return value is stored? is it stored in stack? in heap? and does it remain in memory until my program finished?
if it be stored in stack can i be sure that my class values never change?
please explain the mechanism of these return. and if returning structure is different to returning class?
MyClass myClass; is stored on the stack. It's destroyed immediately after myFunction() exits.
When you return it, a copy is made on the stack. This copy exists until the end of the enclosing expression: cout << myFunction().ch;
Note that if your compiler is smart enough, the second object shouldn't be created at all. Rather, the first object will live until the end of the enclosing expression. This is called NRVO, named return value optimization.
Also note that the standard doesn't define "stack". But any common implementation will use a stack in this case.
if returning structure is different to returning class?
There are no structures in C++; keyword struct creates classes. The only difference between class and struct is the default member access, so the answer is "no".
It's up to the implementation to find a sensible place to store that value. While it's usually on the stack, the language definition does not impose any requirements on where it's actually stored. The returned value is a temporary object, and it gets destroyed at the end of the full statement where it is created; that is, it gets destroyed at the ; at the end of the line that calls myFunction().
When you create an object in any function it's destroyed as soon as the function execution is finished just like in variables.
But when you return a object from a function firstly compiler creates a local instance of this object in heap called unnamed_temporary then destroyes the object you created. And copies the contents of unnamed_temporary on call. Then it destroyes this unnamed _temporary also.
Anything you create without the keyword new will be created in stack.
Yes,contets of your variable ch will not change unless you access that variable and change it yourself.
The instance returned by myFunction is temporary, it disappears when it stop to be useful, so it doesn't exist after after the cout <<.... Just add a destructor and you will see when it is called.
What do you mean about can i be sure that my class values never change? ? You get a copy of the instance.
returning structure is different to returning class? : a struct is like a class where all is public by default, this is the alone difference.
Your function is returning a copy of an object. It will be stored in the stack in memory.
The returning obj. will exist until the scope of that function. After that, it will be destroyed. Then, your expression cout<<function(); will also have the copy of that obj. which is returned by the function. IT will be completely destroyed after the running of this cout<<function(); expression.

How come we can return references to member variables of a class

I want to understand why is it possible to return a reference to a class member variable in C++, such as in the following example:
class Foo
{
int x;
public:
int& get_pvar()
{
return x;
}};
Apparently we can access the variable x in main(), create a reference to it and then alter its contents:
Foo obj;
int& ref = obj.get_pvar();
ref = 7;
But how is this possible? x does not have global scope, neither is it a static member of the class. It is defined within the class. So, it should have local scope. So, why isn't it an error to return a reference to it and even create a reference to it in main()?
You are confusing scope and lifetime. Those are two related, but ultimately different concepts.
The scope of the name x is the class scope. You can only use the unqualified name x for the member inside members functions (and some other minutia, irrelevant here) of the class.
The lifetime of the member object named x is the same as the enclosing class object. In this case, the lifetime of obj.x is the same as obj. Since you return a reference to an object within its lifetime, everything checks out.
The reason for your confusion may stem from learning that objects with automatic storage duration, like the following:
{
int x;
}
Have their lifetime bound to their lexical scope (they can only be named inside those curly braces, their scope). But while it's true for those objects, it is not something that holds in general. Class objects can live independently of the scope of their name (as you saw). And some objects can have a lifetime but no scope and name. Consider:
auto* p = new Foo();
The new expression creates an object, but it has no name! So there is no scope to even speak of. Here p is the name of a pointer, not of the newly created object.
"Scope" and "access control" are things that apply to names, not variables. Saying that x is private in Foo means that if we write x in some unrelated context, the name will not be found.
But the variable can still be accessed in other contexts if you don't require looking up the name.
That is how references or pointers work. If you decided to export the address of your private field it can be changed from the outside.
It is a bad practice but the language doesn't have any mechanism to prevent the developer from doing it.

Callback function "C style" called from C++ object

I'm learning on the field about callback functions. Thanks to some of you I learned much.
I'm using a C++ instance of an object that must call a callback function: a single function, not a C++ method as the follow:
MyObj *obj = new MyObj();
obj->callback(function);
//callback
void funtion()
{
int i = 10;
...
}
My doubt is the following:
if different instances of MyObj invoke the callback, do they will create different "instances" of "function" with their own local variables? in other words are there different "i = 10" in memory for each object invocation or the risk is that the same "i" is shared?
Thank you
There is no such thing as an "instance" of a function. All local variables of a function, member or free-standing, are placed in the automatic storage area (also known as "on the stack"). These variables stay in the automatic storage area until they are no longer needed because their scope has ended, and then get discarded.
Each thread running your function concurrently will have its own copy of the local variables - in your case, each one will have its own i.
Note that if you want to share a variable among multiple invocations, C++ lets you do that by marking the variable inside the function static:
void funtion()
{
static int i = 10;
...
}
Now all invocations of function share the same variable i. Moreover, the value of i will persist across multiple invocations: for example, if one call sets i to 20 before exiting, and then another call enters the function, the value of i would remain 20, not 10, because the initialization of i is performed only once in the run time of your program.

how can I check if an object exists in C++

I am trying to write a function that will check if an object exists:
bool UnloadingBay::isEmpty() {
bool isEmpty = true;
if(this->unloadingShip != NULL) {
isEmpty = false;
}
return isEmpty;
}
I am pretty new to C++ and not sure if my Java background is confusing something, but the compiler gives an error:
UnloadingBay.cpp:36: error: no match for ‘operator!=’ in ‘((UnloadingBay*)this)->UnloadingBay::unloadingShip != 0’
I can't seem to figure out why it doesn't work.
Here is the declaration for class UnloadingBay:
class UnloadingBay {
private:
Ship unloadingShip;
public:
UnloadingBay();
~UnloadingBay();
void unloadContainer(Container container);
void loadContainer(Container container);
void dockShip(Ship ship);
void undockShip(Ship ship);
bool isEmpty();
};
It sounds like you may need a primer on the concept of a "variable" in C++.
In C++ every variable's lifetime is tied to it's encompassing scope. The simplest example of this is a function's local variables:
void foo() // foo scope begins
{
UnloadingShip anUnloadingShip; // constructed with default constructor
// do stuff without fear!
anUnloadingShip.Unload();
} // // foo scope ends, anything associated with it guaranteed to go away
In the above code "anUnloadingShip" is default constructed when the function foo is entered (ie its scope is entered). No "new" required. When the encompassing scope goes away (in this case when foo exits), your user-defined destructor is automatically called to clean up the UnloadingShip. The associated memory is automatically cleaned up.
When the encompassing scope is a C++ class (that is to say a member variable):
class UnloadingBay
{
int foo;
UnloadingShip unloadingShip;
};
the lifetime is tied to the instances of the class, so when our function creates an "UnloadingBay"
void bar2()
{
UnloadingBay aBay; /*no new required, default constructor called,
which calls UnloadingShip's constructor for
it's member unloadingShip*/
// do stuff!
} /*destructor fires, which in turn trigger's member's destructors*/
the members of aBay are constructed and live as long as "aBay" lives.
This is all figured out at compile time. There is no run-time reference counting preventing destruction. No considerations are made for anything else that might refer to or point to that variable. The compiler analyzes the functions we wrote to determine the scope, and therefore lifetime, of the variables. The compiler sees where a variable's scope ends and anything needed to clean up that variable will get inserted at compile time.
"new", "NULL", (don't forget "delete") in C++ come into play with pointers. Pointers are a type of variable that holds a memory address of some object. Programmers use the value "NULL" to indicate that a pointer doesn't hold an address (ie it doesn't point to anything). If you aren't using pointers, you don't need to think about NULL.
Until you've mastered how variables in C++ go in and out of scope, avoid pointers. It's another topic entirely.
Good luck!
I'm assuming unloadingShip is an object and not a pointer so the value could never be NULL.
ie.
SomeClass unloadingShip
versus
SomeClass *unloadingShip
Well, you don't have to write so much code to check if a pointer is NULL or not. The method could be a lot simpler:
bool UnloadingBay::isEmpty() const {
return unloadingShip == NULL;
}
Plus, it should be marked as "const" because it does not modify the state of the object and can be called on constant instances as well.
In your case, "unloadingShip" is an object of class "UnloadingShip" which is not dynamically allocated (except when the whole class "UnloadingBay" is allocated dynamically). Thus, checking if it equals to NULL doesn't make sense because it is not a pointer.
For checking, if an object exists, you can consider going this way:
create a pointer to your object:
someClass *myObj = NULL // Make it null
and now where you pass this pointer, you can check:
if(!myObj) // if its set null, it wont pass this condition
myObj = new someClass();
and then in case you want to delete, you can do this:
if(myobj)
{
delete myObj;
myObj = NULL;
}
so in this way, you can have a good control on checking whether your object exists, before deleting it or before creating a new one.
Hope this helps!