C++, constructor, destructor - c++

As a general opening question, it can be stated as why some times destructor gets called in the middle of the code?!
what are the different possible scenarios can call a destructor.?
I would like to understand the similar effect in the following code
class complex
{
private:
double re, im;
protected:
public:
complex()
{
cout << "def const " << endl;
}
complex(double r, double i)
{
cout << "parameterized " << endl;
re = r;
im = i;
}
void setdata(double r, double i)
{
re = r;
im = i;
}
void getdata()
{
cout << "enter real" << endl;
cin >> re;
cout << "enter im" << endl;
cin >> im;
}
//there are 3(?) possible variants of addition...check
//1st
void add(complex c1, complex c2)
{
cout << "in add" << endl;
re = c1.re + c2.re;
im = c1.im + c2.im;
}
//2nd
void add(complex c)
{
cout << "in add" << endl;
re += c.re;
im += c.im;
}
//3rd --- (???)
// complex add(complex c1, complex c2)
// {
// complex retc;
// retc.re = c1.re + c2.re;
// retc.im = c1.im + c2.im;
//
// return retc; //this one is very weird
// }
void display()
{
cout << endl << re << " + " << im << "i" << endl;
}
void mul(complex c1, complex c2)
{
cout << "in mul" << endl;
re = c1.re*c2.re - c1.im*c2.im;
im = c1.re*c2.im + c1.re*c2.im;
}
complex mul(complex c)
{
cout << "in mul" << endl;
complex retc;
retc.re = re*c.re - im*c.im;
retc.im = re*c.im + c.re*im;
return retc;
}
~complex()
{
cout << re << " + " << im << "i" << endl;
cout << "dest" << endl;
}
};
int main()
{
complex c1;
c1.getdata();
complex c2(5, 5);
complex c3;
c3.add(c1, c2); //to store the answer of c1 + c2 we need c3 object
c3.display();
//perform c1 + c2 * c3
complex c4;
c4.add(c1, c2.mul(c3)); //can not use mul(c2, c3) for c2 * c3...why???!
cout << "ans1" << endl;
c4.display();
//or we can also do...
c1.add(c2.mul(c3)); //but this will modify c1
cout << "ans2" << endl;
c1.display();
return 0;
}
following is the output
def const
enter real
1
enter im
2
parameterized
def const
in add
1 + 2i
dest
5 + 5i
dest
6 + 7i
def const
in mul
def const
in add
1 + 2i
dest
-5 + 65i
dest
6 + 7i
dest
ans1
-4 + 67i
in mul
def const
in add
-5 + 65i
dest
6 + 7i
dest
ans2
-4 + 67i
-4 + 67i
dest
6 + 7i
dest
5 + 5i
dest
-4 + 67i
dest
any idea why do destructors get called in the middle of nowhere!?

why some times destructor gets called in the middle of the code?
Take these methods for illustration:
void mul(complex c1, complex c2)
{
cout << "in mul" << endl;
re = c1.re*c2.re - c1.im*c2.im;
im = c1.re*c2.im + c1.re*c2.im;
}
void add(complex c1, complex c2)
{
cout << "in add" << endl;
re = c1.re + c2.re;
im = c1.im + c2.im;
}
You invoke it with:
c4.add(c1, c2.mul(c3));
Both add() and mul() are receiving their parameters by value. When the compiler sees a pass-by-value parameter, it creates a new version of the parameter object by means of the copy constructor. All classes have a default copy constructor, which assigns each field member one by one. This new version is used throughout the method, and finally destroyed.
So, when you call mul() in c2 with c3 as parameter, a new complex object is created from c3, and when the end of mul() is reached, it is destroyed. The same happens with the call to add() with c1 and the result of c2.mul(c3).
If you want to avoid this copying (which takes time and resources), then you should change the kind of parameter passing in your functions. Specifically, you can pass them by pointer or by reference. The problem is that this would allow modifications of them inside the function: but in the concrete case of pass-by-reference, you can modify it with const, which gets you the best of both worlds: you get the object efficiently passed without the possibility of modification.
void mul(const complex &c1, const complex &c2)
{
cout << "in mul" << endl;
re = c1.re*c2.re - c1.im*c2.im;
im = c1.re*c2.im + c1.re*c2.im;
}
void add(const complex &c1, const complex &c2)
{
cout << "in add" << endl;
re = c1.re + c2.re;
im = c1.im + c2.im;
}
Taking into account that the methods above do not modify the instance they are being called against, they can be also const themselves.
void mul(const complex &c1, const complex &c2) const
{
cout << "in mul" << endl;
re = c1.re*c2.re - c1.im*c2.im;
im = c1.re*c2.im + c1.re*c2.im;
}
void add(const complex &c1, const complex &c2) const
{
cout << "in add" << endl;
re = c1.re + c2.re;
im = c1.im + c2.im;
}
Also, since these functions do not require an instance of complex, they could also be independent, friend functions, or static methods. Actually, that is worth another answer.
Just as a rule of thumb, when you have just one argument of the same class, as in void mul(complex c2), that's probably a member of the class; you're going to invoke it as c1.mul( c2 ). When you have two arguments, as in void mul(complex c1, complex c2) then it is an independent function (i.e., you'll invoke it as mul( c1, c2 ), that it can be friend if you want it wrapped inside your class or access to the private member of your class. Normally you create these friend functions because you have an operator with an object of another class (or a primitive) at its left. Another issue is that an independent function should better return a new object instead of modifying one of its arguments... as you can see, it gets more and more complex.
Anyway, these are the signatures your methods should sport:
class complex {
public:
// ... more things...
void mul(complex c2);
complex operator*(const complex &c2);
friend complex operator*(int x, const complex &c1);
// ... more things...
};
Also, instead of tying your class to the console with the display() function, better overload the operator <<, and you'll be able to use that functionality with any stream.
Find the complete code in IDEOne.
Hope this helps.

Destructors are called when you delete a pointer explicitly, at the end of the scope for scope variables and at the end of the statement for temporaries.
In your case in
c4.add(c1, c2.mul(c3));
you need to compute c2.mul(c3). It will create a new complex class instance. It will be kept around for add to execute, and it will be destroyed when the call is done, since it's no longer needed.

First of all keep in mind that you should only concern about calling a destructor for an object created dynamically in run time. One straight forward answer for this is, YOU need to verify your codes carefully and find out all the dynamically created objects in your codes and check exactly when it is going to out of scope i.e. the time/area from when that object is never going to use any more, and exactly that point of time you need to call the destructor of that object to clear heap memory. Please keep in mind that destructor is for releasing/cleaning memory to avoid memory leak and better memory management in a process.

Related

Why return by reference while overloading = operator?

I know there's plenty of questions on this already, so please bear with me on this one.
So I found this question, and I had a doubt about a modification of this.
class Blah {
public:
Blah();
Blah(int x, int y);
int x;
int y;
Blah operator =(Blah rhs);
};
Blah::Blah() {}
Blah::Blah(int xp, int yp) {
x = xp;
y = yp;
}
Blah Blah::operator =(Blah rhs) {
x = rhs.x;
y = rhs.y;
return *this;
}
int main() {
Blah b1(2, 3);
Blah b2(4, 1);
Blah b3(8, 9);
Blah b4(7, 5);
b3 = b4 = b2 = b1;
cout << b3.x << ", " << b3.y << endl;
cout << b4.x << ", " << b4.y << endl;
cout << b2.x << ", " << b2.y << endl;
cout << b1.x << ", " << b1.y << endl;
return 0;
}
So I haven't used return by reference here, while overloading the = operator, and I still get the expected output.
Why should I return by reference? The only difference I see is that copy constructor is called while returning by value but no copy constructor is called while returning by reference.
Could someone please dumb things down for me and explain the concept/idea behind returning by reference? It was taught in my class around almost a year ago, and I still don't understand it.
There is no strict right and wrong here. You can do weird things with operator overloads and sometimes it is appropriate. However, there is rarely a good reason to return a new instance from operator=.
The return value is to enable chaining. Your test for chaining is incomplete. Your line:
b3 = b4 = b2 = b1;
is the same as
b3 = (b4 = (b2 = b1));
And you see expected output for this case. However, chaining like this
(b3 = b4) = b1;
is expected to first assign b4 to b3 then assign b1 to b3. Or you might want to call a method on the returned reference:
(b3 = b4).foo();
As you return a copy, the second assignment will be to a temporary and the member function foo will be called on a temporary, not on b3 as expected. To see this in action consider the output of this
int main() {
Blah b1(2, 3);
Blah b2(4, 1);
Blah b3(8, 9);
Blah b4(7, 5);
(b3 = b4) = b1;
cout << b3.x << ", " << b3.y << endl;
cout << b1.x << ", " << b1.y << endl;
return 0;
}
when returning a copy:
7, 5
2, 3
and when returning a reference:
2, 3
2, 3
The much simpler reason is that you do not want to return a copy when there is no need to make a copy.
Why return by reference while overloading = operator?
Because:
Copying is sometimes expensive, in which case it is good to avoid.
It is conventional. That is also how the built in assignment operators of fundamental types, compiler generated assignment operators of classes, and all the assignment operators of standard types (as far as I know) work.
Given that the special member functions that you've defined don't do anything special, I recommend following class definition instead:
struct Blah {
int x;
int y;
};

Assignment operator overloading: returning void versus returning reference parameter [duplicate]

This question already has answers here:
Why should the assignment operator return a reference to the object?
(4 answers)
Closed 6 years ago.
Some of the assignment overloading operator examples I see online look like this:
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
void operator = (const Distance &D ) {
cout << "assigning..." << endl;
feet = D.feet;
inches = D.inches;
}
// method to display distance
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main() {
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// use assignment operator
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
They return void from the overloaded function. This makes sense to me if D1 is the object being called.
Other examples return a reference to a class object.
#include <iostream>
using namespace std;
class Distance {
private:
int feet; // 0 to infinite
int inches; // 0 to 12
public:
// required constructors
Distance(){
feet = 0;
inches = 0;
}
Distance(int f, int i){
feet = f;
inches = i;
}
Distance& operator = (const Distance &D ) {
cout << "assigning..." << endl;
feet = D.feet;
inches = D.inches;
return *this;
}
// method to display distance
void displayDistance() {
cout << "F: " << feet << " I:" << inches << endl;
}
};
int main() {
Distance D1(11, 10), D2(5, 11);
cout << "First Distance : ";
D1.displayDistance();
cout << "Second Distance :";
D2.displayDistance();
// use assignment operator
D1 = D2;
cout << "First Distance :";
D1.displayDistance();
return 0;
}
This does not make sense to me (when taking the first example into consideration). If in the first example D1 = D2; invokes something like D1.=(D2);, why would the second example work in that case? Is it something like D1 = D1.=(D2);? And does it make any difference at the end of the day?
Although C++ language lets you overload assignment operator with any return type, including void, you should strongly consider following a widespread convention of returning a reference to the assignee from the operator.
The rationale for it is that
A = B;
will work no matter what the assignment returns, while
A = B = C;
which is a perfect chain of assignments will break, unless B = C returns something assignment-compatible to A (which is usually an object of the same type as A).
Another problem is in situations when you must compare the object as part of a larger expression, for example
mytype obj;
while ((obj = read_obj(cin)) != END_OBJ) {
...
}
Hence, the biggest drawback to returning void is inability to chain assignments and use them in places where void is not allowed.
As a convention, assignment operator usually returns reference (to *this); which makes it possible to chain the assignment, just like the behavior of those built-in types. e.g.
Distance D1, D2, D3;
D1 = D2 = D3;
For D1 = D2;, it's equivalent with D1.operator=(D2);. It doesn't change for the 2nd case, the returned value is just discarded. For D1 = D2 = D3;, it's equivalent with D1.operator=(D2.operator=(D3));. Note the returned value (i.e. reference to D2) is used as the argument for the assignment operator called on D1.

In c++ how to avoid print message when I use function which has cout?

If i have two functions A and B, A will print message when we use A. B will use A, but when I use B, I do not want to print anything. How can I do this?
double CTriangle::perimeter() const{
double D = Distance(A, B) + Distance(A, C) + Distance(B, C);
cout << "Perimeter of this triangle is: " << D << endl;
return D;
}
double CTriangle::area() const{
double p = this->perimeter() / 2;
double Area = sqrt(p * (p - Distance(A, B)) * (p - Distance(A, C)) * (p - Distance(B, C)));
cout << "Area of this triangle is: " << Area << endl;
return Area;
}
How about adding a parameter to A(), e.g.
void A(bool verbose = true)
{
if (verbose) cout << "Hello world!" << endl;
}
void B()
{
A(false);
}
int main()
{
A(); // outputs "Hello world!"
B(); // calls A, but no output
return 0;
}
Assuming you don't have any control over the function which does the printing, you can put std::cout into a state where it won't print anything, e.g.:
std::cout.setstate(std::ios_base::failbit); // set error flag, disabling output
double d = this->perimeter();
std::cout.clear(); // clear flags, reenabling output
You can reasonably view the stream state a resource, i.e., it may be reasonable to use RAII to make sure the stream's state gets restored.
If you can change the function which does the unwanted output, I'd recommend rewriting this function to become two functions:
One function which doesn't do any logging and implements the core functionality.
Another function which does logging and calls the other function for the actual functionality.

C++: Parent object change their id attribute without method call

As I specified in the title, this is a problem that puzzled me enormously, and still I can not find a fix for it.
I created a Point class which has three private attributes (_id, _x and _y) with related public get and set methods.
For example, I created three points (G, H, R), where the point G is a "parent". Point H is the prototype of the point G (a clone) and point R will be the outcome of the meeting points (G+H) (addition of the points).
Points sample:
Point G ("pG", 3.5f, 6.5f);
Point H (G.prototype ()); H.setId ("pH");
Point R;
R = G + H;
The program works correctly, but unfortunately after the operation {R=G+H}, _id attribute of point G becomes the clone attribute of point R, I do not understand why this is happening because the evaluation is done from right to left (H+, +G, =R).
The question is why G point attribute changes itself?
Code where the problem occurs:
#include <iostream>
#include <string>
using namespace std;
class Point
{
private:
string _id;
double _x;
double _y;
public:
Point(string id="undefined", double x = 0.00f, double y = 0.00f)
:_id(id), _x(x), _y(y){}
~Point(){}
public:
// Getters methods
string getId() const { return _id;}
double getX() const { return _x; }
double getY() const { return _y; }
void setId(string id) { _id = id; }
// Setters methods
void setX(double n = 0.00f) { _x = n; }
void setY(double n = 0.00f) { _y = n; }
Point prototype() { return Point(_id, _x, _y); }
Point operator+ (const Point& p)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
_id.append("+").append(p._id),
_x+p._x,
_y+p._y
);
}
Point operator= (const Point& p)
{
cout << "Operator = called, returning a new object Point(p._id, p._x, p._y)" << endl;
_id=p._id;
_x=p._x;
_y=p._y;
return *this;
}
};
int main()
{
Point G("G",10.0f, 10.0f);
Point H(G.prototype()); H.setId("H");
Point R;
R = G + H;
cout << "object Point {id: " << G.getId() << ", x: " << G.getX() << ", y: " << G.getY() << "}" << endl;
cout << "object Point {id: " << H.getId() << ", x: " << H.getX() << ", y: " << H.getY() << "}" << endl;
cout << "object Point {id: " << R.getId() << ", x: " << R.getX() << ", y: " << R.getY() << "}" << endl;
return 0;
}
Thanks in advance!
Point operator+ (const Point& p)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
_id.append("+").append(p._id), // HERE
_x+p._x,
_y+p._y
);
}
In this line, you modify _id property of this object. As a rule of thumb, binary + operator should be a const member or - IMO cleaner - a static method taking two const reference arguments.
BTW, you can add strings in C++ by just applying + operator to them (_id + "+" + p._id).
If you implement your binary arithmetic operators as members, you should consider making the operator a const member. This would catch the obvious modification in your implementation (the implementation is made out of line to avoid including unrelated code):
Point Point::operator+ (const Point& p) const
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
_id.append("+").append(p._id),
_x+p._x,
_y+p._y
);
}
The operation _id.append("+") actually operates on this->_id, i.e., the _id member of the left hand operand. Since you member operator isn't const, the compiler lets you do the modification. This is probably not what you intended to do. You probably rather wanted to write:
Point Point::operator+ (const Point& p) const
{
cout << "Operator + called, returning a new object\n";
return Point
(
_id + "+" + p._id,
_x+p._x,
_y+p._y
);
}
... which creates a suitable temporary string with the desired value (I also replaced the excessive use of std::endl).
This line in the operator+ overload:
_id.append("+").append(p._id),
You have to be very careful here, you are currently in an object (in your example this would be the G object). append actually alters the local string, so your code is appending + then p._id then deep copying that to the returned value.
A quick fix is to change this to a temporary that holds what you need:
_id + "+" + p._id
To avoid problems like this in the future, you should declare operator overloads as a friend method so it's extremely clear what you're operating on.
friend Point operator+ (const Point& lhs, const Point& rhs)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
lhs._id.append("+").append(rhs._id), //COMPILER ERROR! We're modifying the const "lhs"!
lhs._x+rhs._x,
lhs._y+rhs._y
);
}
So let's change this to:
friend Point operator+ (const Point& lhs, const Point& rhs)
{
cout << "Operator + called, returning a new object" << endl;
return Point
(
lhs._id + "+" + rhs._id, // no longer modifying lhs -- all is well!
lhs._x+rhs._x,
lhs._y+rhs._y
);
}

Combining overloaded operators with 'new' object

i'd like to ask something rather difficult for me; I have to make a calendar-type program, but with an overloaded '+=' operator.
So it goes like this:
template<typename T1,typename T2,typename T3> //int,int,int
class T_sort_data{
T1 p1;
T2 p2;
T3 p3;
public:
T_sort_data(){
cout << "\n\t Constructed at [" << this << "]\n";};
/ friend ostream& operator<<(ostream& os,const T_sort_data& obj) // get function
{
os << "\nDay : " << obj.p1 << " \n";
os << "Month : " << obj.p2 << " \n";
os << "Year : " << obj.p3 << " \n";
return os;
}*/
void set_date(){
int dd,mm,yy;
cout << "\n\n\tPlease input the day, the month and the year : \n\n";
cin >> dd >> mm >> yy;
p1 = dd;
p2 = mm;
p3 = yy;
}
// validator here, which works ...
T_sort_data<int,int,int>& operator+=(const T_sort_data<int,int,int>& second)
{
p1+=second.p1;
return *this;
}
friend istream& operator>>(istream& is, T_sort_data& obj) // set function
{
is >> obj.p1;
is >> obj.p2;
is >> obj.p3;
return is;
}
~T_sort_data(){
cout << "\n\t Deconstructed [" << this << "]\n";};
};
int main(){
T_sort_data<int,int,int> * a = new T_sort_data<int,int,int> ;
bool more = true;
string answ;
a->set_date();
//cin >> a; (this doesn't work)
//validator goes here
//a += a; (this, again, doesn't work)
delete a;
return 0;
}
Whenever I make an object using "T_sort_data a;" those operations work fine, but whenever I use "T_sort_data * a = new T_sort_data;"
shit hits the fan.
Can anyone help me with this?
You didn't post exactly what is going wrong so I have to infer that from the code.
The issue that you're running into is that overloaded operators work on instances or references to objects, not on pointers to objects. In the cases where your code doesn't work, you're dealing with pointers to objects. So, in order to use your overloaded operators, you need to dereference the pointer (effectively turning it from a pointer pointing to a value into the value itself) before applying the operator, for example:
cin >> *a;
or
*a += *a;
T_sort_data a is a variable of type T_sort_data.
T_sort_data * a is a variable of type pointer to T_sort_data.
Your overloaded operators expect their operands to be of type T_sort_data, not pointer to T_sort_data. Use the unary * operator to dereference the pointers, so that the operand types are what the operators expect.
This is pretty fundamental. Here's the same thing with int and std::cout: http://codepad.org/N07Xckdy