Just a tiny question:
Can you tell me what's the issue here in this code ? It should print out 9 but it does 4.8921e-270, however, when uncommenting line 4, it works just fine, too.
I don't understand what might be wrong here. Thank you !
Code:
double& foo() {
double x = 9;
double &y = x;
//cout << y << "\n";
return y;
}
int main() {
cout << foo() << "\n";
}
Result:
4.8921e-270
It is a bad idea to return references/pointers to objects on the stack. They are likely destroyed when you leave the function. Try returning it as per value:
double foo() {
double x = 9;
double &y = x;
//cout << y << "\n";
return y;
}
Now the return value is copied instead of a reference to an object that is probably not existing anymore.
You are returning a reference to a local object, the object ceases to exist when foo completes, and then you get Undefined Behavior when you dereference it.
double foo() {
double x = 9;
double &y = x;
//cout << y << "\n";
return y;
}
Never a good idea to return references to objects on stack. Most likely they would be disappear when you leave the function. You might try returning it as per value.
You return a reference to a local variable - since the local variable goes out of scope as soon as foo() returns, the value no longer exists.
So you should either just change the return type to double (highly recommended) and return x or (if you absolutely want/have to return a reference) use a static variable instead:
double& foo() {
static double x = 9;
double &y = x;
return y;
}
I often return data members of a class by const ref:
class BigThing {...};
class Foo
{
public:
const BigThing & getBT() const { return bt; } // For constant BigThing.
BigThing & getBT() { return bt; } // For mutable BigThing.
private:
BigThing bt;
};
Then as long as your instance of Foo is in scope (you don't want to return a ref to a local variable) then using one of the getBT() should be safe and efficient.
Related
I am quite new in C++ programming, so maybe that's why I can't figure out why this assignment is not working.
In my class, I want to overload "=" operator.
I have specified a function, that outputs variables as an array. In overloading, I want to assign those variables to new object.
obj_new = obj_with_variables
overloading:
obj_new_x=obj_with_values_parameters()[0];
obj_new_y=obj_with_values_parameters()[1];
Here is a code:
// Test1.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
#include "string"
using namespace std;
class Vector2D
{
public:
Vector2D()
{
}
Vector2D(int& a, int& b)
:x(a), y(b)
{
}
void Drukuj()
{
cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int&a, int&b)
{
x = a;
y = b;
}
int* Wspolrzedne()
{
int tab[2] = { x,y };
return tab;
}
void operator = (Vector2D& obj)
{
int* a = obj.Wspolrzedne();
cout << a[0] << "\n";
x = a[0];
cout << x << " what? \n";
y = a[1];
}
private:
int x, y;
};
int main()
{
int x1 = 2, x2 = 3;
Vector2D wektor(x1, x2);
wektor.Drukuj();
Vector2D wektor2;
wektor2 = wektor;
wektor2.Drukuj();
wektor.Drukuj();
return 0;
}
The problem is that it assigns some strange values. However, if I don't use a reference, but declare 2 int values (j,k) and assign array element to them [0,1], it works fine.
Also, when using static numbers (for example, instead of a[0] ; use "2") it works fine too.
What is going on?
I would be glad if somebody could point me to right answer/ resources.
Regards,
In your member function int* Wspolrzedne(), you return the address of local variable tab. Accessing this variable once its life time has ended, as you do in your = operator, is undefined behaviour.
Your code has undefined behavior because operator= is accessing invalid data. Wspolrzedne() is returning a pointer to a local variable tab that goes out of scope when Wspolrzedne() exits, thus the a pointer used in operator= is not pointing at valid data.
If you want Wspolrzedne() to return multiple values, you need to have it return (by value) an instance of a struct or class to hold them. Try something more like this:
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
struct Coordinate {
int x;
int y;
};
class Vector2D
{
public:
Vector2D()
: x(0), y(0)
{
}
Vector2D(int a, int b)
: x(a), y(b)
{
}
Vector2D(const Coordinate &c)
: x(c.x), y(c.y)
{
}
Vector2D(const Vector2D &src)
: x(src.x), y(src.y)
{
}
void Drukuj()
{
cout << "wektor [" << x << ',' << y << "] \n";
}
void Wspolrzedne(int a, int b)
{
x = a;
y = b;
}
void Wspolrzedne(const Coordinate &c)
{
x = c.x;
y = c.y;
}
Coordinate Wspolrzedne()
{
Coordinate c = { x, y };
return c;
}
Vector2D& operator=(const Vector2D &obj)
{
Coordinate c = obj.Wspolrzedne();
cout << c.x << ',' << c.y << "\n";
Wspolrzedne(c);
return *this;
}
private:
int x;
int y;
};
On the other hand, there is no real reason to even have operator= call Wspolrzedne() to get the coordinates at all, when it can just access obj.x and obj.y directly instead:
Vector2D& operator=(const Vector2D &obj)
{
x = obj.x;
y = obj.y;
return *this;
}
In which case, you can simply eliminate your operator= altogether, and let the compiler provide a default-generated implementation that does the exact same thing for you.
Your interface is dangerous, as returning raw pointers from functions means the caller must know how to manage it. That is, the caller needs to be astutely aware of the answers to questions like, "should the caller delete the pointer or does the object I got it from retain ownership?" What is this pointer pointing to? If it's an array, now many elements are there? If I must delete it, do I use delete or delete[]?
And so on. This is not good because it's very, very error prone.
Next you have a function that returns a pointer to stack-local data. When the function returns, that memory is already invalid so the return value is always going to result in undefined behavior to read.
int* Wspolrzedne()
{
int tab[2] = { x,y };
return tab; // BAD - returns pointer to function stack data
}
Where does tab live? It's destroyed when the function exits, but you're returning a pointer to it.
This is a dangerous interface and should be changed. Perhaps you should return the values as a pair:
std::pair<int, int> Wspolrzedne()
{
return std::pair{ x,y }; // assuming c++17
// return std::pair<int, int>{x, y}; // older compilers
}
An interface like this avoids pointers, and removes all the issues mentioned above.
I have a basic understanding of this pointer in C++.While studying have come across the following code:
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
//Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
My issue is why the compiler deosn't report an error where I am returning a this pointer in SetX and SetY functions but haven't stated the return type as a pointer?
This comes because you're returning *this not this.
this is the pointer to a object of type Test. This means the this-variable basically holds the address where the object is stored. To access the object on which this points you use the *.
So you're returning the actual object on which you this Pointer points at.
EDIT
The problem why your code does not work in the way you want it to do is caused by the fact, that you're working on the stack.
Let's take a look at the addresses:
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
//Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) {
y = b;
cout << this << endl; // >> 0x29ff18
return *this;
}
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
cout << &obj1 << endl; // >> 0x29ff10
obj1 = obj1.setX(10).setY(20);
cout << &obj1 << endl; // >> 0x29ff10
//obj1.setY(20);
obj1.print();
return 0;
}
As you can see, the object where this points at is at a different address within you setY method compared to the main. This is because the object is copied to the stackframe of the setY method - so within setX and setY you're working with a copy of obj1
If you're doing obj1.setX(10).setY(20); you basically copy the object obj1 and use it within setX and the return object of setX is then used in setY. If you want to save the last copy, you have to reassign it to obj1.
Your solution to the problem works, but is grossly inefficient. The last paragraph describing what is happening is incorrect. setx is called with and uses obj1. sety is called with and uses copy of obj1. obj1 is then assigned copy of copy of obj1 returned by sety. The address doesn't change because obj1's storage is being overwritten, not replaced. Add a copy constructor and an assignment operator and you can watch what's really happening. The recommended solution is to use references to the same object throughout and chaining as per #πάνταῥεῖ 's answer below. – user4581301
My issue is why the compiler deosn't report an error where I am returning a this pointer in SetX and SetY functions but haven't stated the return type as a pointer?
It's completely valid syntax, so the compiler isn't supposed to return an error message. The problem is that you're using copies of this* with your return type.
To chain operations properly to operate on the original instance return a reference to this:
Test& setX(int a) { x = a; return *this; }
// ^
Test& setY(int b) { y = b; return *this; }
// ^
Otherwise you're returning an unrelated copy of your class.
What's the difference in usage of function get1() and get2()?
struct x
{
float get1() const
{
float fx = 4;
fx += 1.5f;
return fx;
}
float& get2() const
{
float fx = 4;
fx += 1.5f;
return fx;
}
};
int main()
{
x t;
float x1 = t.get1();
float/*&*/ x2 = t.get2();
cout << x1 << endl;
cout << x2 << endl;
cin.get();
}
As i understand, get2() can only be const class member..
It's not clear for me completely. If someone can point me to a reference or just a short but complete solution, would be nice.
In your case, get2() invokes undefined behavior because you return a reference to a method-local that goes out of scope.
The difference is that returning float returns a float value, while float & returns a reference to a float. The reference can be used to alter the data of the referent; when returning by value you just get a copy.
It sounds like you are just confused about what references do, so here is the colloquial definition: a reference is another name for an object. That means that a reference requires the existence of its target to exist elsewhere, very similar to a (non-null) pointer.
Let me write a better example to illustrate the difference:
struct x
{
x() : data(0) { }
float get1() const
{
return data;
}
// Cannot be const now, because we can't return a non-const reference to what
// would be a const data member. (If this method were const then data would be a
// const float, and that cannot bind to float &.)
float & get2()
{
return data;
}
private:
float data;
};
Now we have two methods, one that returns data and one that returns a reference to it. The difference here is that with get2() you can actually change the value of x::data:
x an_x;
float a = an_x.get1(); // a is 0
a = 5; // a is 5, an_x.data is still 0
a = x.get1(); // a is 0 again, because an_x.data did not change
float & b = an_x.get2(); // b is 0
b = 5; // b is 5, and so is an_x.data!
a = x.get1(); // a is now 5, because an_x.data is 5
Notably, returning a reference makes the result of the expression an lvalue:
an_x.get1() = 5; // Compile-time error, because a float is not an lvalue.
an_x.get2() = 5; // Compiles, and sets an_x.data to 5.
This is a technique used by the standard library containers; vector<int> for example returns int & from its non-const operator[] overload, which is why some_vector[0] = 5; compiles and works as you would expect.
float fx = 4;
In your case fx is local variable. It will die once you come out of function. If you are returning float then you are making copy of value, so even fx die, no problem. But if you are returning float&, you are returning reference to died variable. Which is undefined behaviour.
Copying is costly operation. When you return reference, you are not making actual copy, but you are returning address of varaiable. You should return reference if your variable will alive after returning from function. But in your case, fx will die once you come out of function.
I simulated your case in below blocks of code, you can compare the output of two case for making clearly. Hope it help.
#include <iostream>
class A
{
public:
A()
{
std::cout << this << ": A()\n";
}
A(const A&)
{
std::cout << this << ": Copy constructor\n";
}
~A()
{
std::cout << this << ": ~A()\n";
}
};
struct x
{
A get1() const
{
A a;
return a;
}
A &get2() const
{
A a;
return a;
}
};
int main(int argc, char *argv[])
{
x t;
/*{
t.get1();
}*/
{
t.get2();
}
std::cin.get();
}
Please tell me the use of cascading, and when to use & before function like this int &func()
Where should i use that please give me small example, Thanks. I think it does return an address but no idea how to use.
You are about to commit a very common newbie mistake in C++, namely returning references to dead objects.
int &GetNumber()
{
int number = 123;
return number;
}
int main()
{
int x = GetNumber();
int y = x + 1;
}
Looks innocent but will create so-called undefined behaviour. This means that the program may do whatever it wants to - it will likely crash, or it will sometimes crash. In any case, it won't be safe. Your compiler may even warn you if you attempt to do this. The reason is that by the time GetNumber has finished, the local number is destroyed, and you end up with a reference to a destroyed object.
Usually, you will want to return a copy instead of a reference. This is the "normal" thing to do in C++:
int GetNumber() // now OK
{
int number = 123;
return number;
}
int main()
{
int x = GetNumber();
int y = x + 1;
}
Returning references is only safe when you know that the object referred to will continue to exist after the function returns. One example is when you are just returning a reference you were passed:
int &MyFunction(int &number)
{
// do something
return number;
}
This then allows you to chain functions:
struct Example
{
Example &MyFunction(Example &example)
{
// do something
return example;
}
};
int main()
{
Example example;
example.MyFunction(example).MyFunction(example).MyFunction(example);
}
Now, if this example strikes you as particularly useless (as it should), look at how the standard library handles << calls with std::ostream for a realistic use case.
std::cout << 1 << "a" << 0.5;
This syntax works because each operator<< call returns a reference to std::cout.
when to use &
Return by value vs return by reference
You usually return a reference when you want a caller to be able to change the original variable. Example can be returning elements of an array
struct Array
{
int values[ 10];
};
// Returns a reference to the nIndex element of rArray
int& Value( Array &rArray, int nIndex)
{
return Array.values[ nIndex];
}
int main()
{
Array myArray;
// Set the 10th element of sMyArray to the value 5
Value( myArray, 10) = 5;
assert( myArray.values[ 10] == 5); // OK
return 0;
}
Another example is returning reference to class member. You want to return original variable, not a copy of it. Consider:
struct A {
int something;
int f() { return something; }
int& g() { return something; }
};
int main()
{
A myA;
int i = myA.f(); // return by value: not original
// int but its copy with same value
i = 200;
assert( myA.something == 200); // fail
return 0;
}
but:
int main()
{
A myA;
int& i = myA.g(); // return by reference: original
// variable is referenced by i now
i = 200;
assert( myA.something == 200); // OK
return 0;
}
Operator chaining
Operator chaining is made to allow for expressions like:
a = b + c + d;
or
std::cout << "this" << " and " << "this";
Usually there is choice between returning by value or by reference made by considering the meaning of the operator or independent factors like for example that std::istream and std::ostream are not copyable, so trying to return objects of those types by value is an error.
Below given program prints x = 10 y = 0
#include<iostream>
using namespace std;
class Test
{
private:
int x;
int y;
public:
Test (int x = 0, int y = 0) { this->x = x; this->y = y; }
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
void print() { cout << "x = " << x << " y = " << y << endl; }
};
int main()
{
Test obj1;
obj1.setX(10).setY(20);
obj1.print();
return 0;
}
but if we replace
Test setX(int a) { x = a; return *this; }
Test setY(int b) { y = b; return *this; }
with
Test &setX(int a) { x = a; return *this; }
Test &setY(int b) { y = b; return *this; }
output is x = 10 y = 20
Can anyone explain why this is happening?
When you return a plain object rather than a reference, you're returning a copy of the object on which you called the method. setY acts on that copy (which is a temporary), then the copy is destructed.
When you return a reference, all the calls operate on the same object, so you get the behavior you're looking for.
The first call to setX() returns a temporary copy of obj1 and the call to setY() modifies the temporary. Subsequent call to print() displays the state of obj1 and since in obj1 the y member variable was never modified it remains zero.
When you replace the return types with references, no temporary copy is made the both calls to setX() and setY() operate on obj.
Lets go back to basis about object oriented programming.
Lets use a metaphor - say a bus.
A bus has certain properties that can be changed - e.g. fuel.
So if you have a function (top up the fuel) you do not need a new bus that is exactly the same as the last one bit with a fuel tank that is full.
So going back to the original question.
Test setX(int a) { x = a; return *this; }
should read
void setX(int a) { x = a; }
etc.
You have the same object but the fuel may be topped up (or x in this case)
In the First case you are returning the object by value, Hence the copy of object will be created and returned.
So
obj1.setX(10) will return a copy of test and than .setY(20) will work on that copy thats why its effects are not on obj1 .
while in second case a reference to object is returned and hence .setY(20) will work on obj1 itself . Hence the output.
This pinter contain address of a object
In first case
in setx fun this pointer return x and and not free for return y value at simultaneously therfore he send copy of y not address of y.
In second case
This both function are different both have own this pointer
So they send address of both x and y