constructor and destructor

S

sahukar praveen

Hello,

This is the program that I am trying. The program executes but does not give
me a desired output.

**********************************************
#include <iostream.h>
#include <iomanip.h>
#include <string.h>

class string{
int length;
char *str;
public:
string()
{
length = 0;
str = new char [length + 1];
strcpy(str, "\0");
}
string(const char *string)
{
cout<< "In the constructor" <<endl;
length = strlen(string);
str = new char [length + 1];
strcpy (str, string);
}
void display (void)
{
cout <<"The length is : " << length<< endl;
cout <<"The string is : " << str << endl;
}
~string()
{
cout << "In the destructor " << length << endl;
delete [] str;
}
};

void main (void)
{
string A;

A.display();
A = string("Praveen"); //explicit call
A.display();
}
********************************************************

The output that I get is

The length is : 0
The string is :
In the constructor
In the destructor 7
The length is : 7
The string is : èö
In the destructor 7


Now my question is

1. why is the "destructor 7" called twice? I would expect "destructor 0" to
be called once and "destructor 7" called the next time. Am I correct?
2. I want to know is that line having a comment "explicit call" correct?
Can I make a call like this?

I would assume that my program has a bug (or is wrong) but I can not find
out. Please Help.

Thanks and Regards,
Praveen Kumar
 
R

red floyd

sahukar said:
Hello,

This is the program that I am trying. The program executes but does not give
me a desired output.

**********************************************
#include <iostream.h>
#include <iomanip.h>
#include <string.h>

class string{
int length;
char *str;
public:
string()
{
length = 0;
str = new char [length + 1];
strcpy(str, "\0");
}
string(const char *string)
{
cout<< "In the constructor" <<endl;
length = strlen(string);
str = new char [length + 1];
strcpy (str, string);
}
void display (void)
{
cout <<"The length is : " << length<< endl;
cout <<"The string is : " << str << endl;
}
~string()
{
cout << "In the destructor " << length << endl;
delete [] str;
}
};

void main (void)
{
string A;

A.display();
A = string("Praveen"); //explicit call
A.display();
}
********************************************************

The output that I get is

The length is : 0
The string is :
In the constructor
In the destructor 7
The length is : 7
The string is : èö
In the destructor 7


Now my question is

1. why is the "destructor 7" called twice? I would expect "destructor 0" to
be called once and "destructor 7" called the next time. Am I correct?
2. I want to know is that line having a comment "explicit call" correct?
Can I make a call like this?

I would assume that my program has a bug (or is wrong) but I can not find
out. Please Help.

1. main returns int, not void
2. I believe that the first destructor 7 call is for the temporary created by
string("Praveen")
3. You're getting garbage before the second destructor 7 because you don't have
an assignment operator.

What's happening is this:

* A is created length 0
* you display that.
* an unnamed temp is created length 7 containng "Praveen".
* You *BITWISE COPY* it to A (since you don't have an assignment operator),
meaning that A and your unnamed temp have the same value in str
* the unnamed temp is destroyed, destructor called, str is delete[] ed.
HOWEVER!!!! A.str still points to that delete[]'ed memory, and is not a valid
pointer now.
You display A, which puts out the eo garbage
You destroy A, which calls delete[] on an invalid pointe.

You need something like the following inside string:


string& operator=(const string& s)
{
if (str != s.str)
{
char *temp = new char[s.length + 1];
std::strcpy(temp,s.str);
delete[] str;
str = temp;
length = s.length;
}
return *this;
}

Your assignments will then work properly.
 
K

Karl Heinz Buchegger

red said:
Your assignments will then work properly.

But the class still contains a flaw.
The OP needs a copy constructor too.

Rule of three:

Whenever you need one of destructor, copy constructor, assignment operator
you most always need all of them.
 
S

sahukar praveen

Hello,

Thanks for the help. I added a function for assignment operator and a copy
constructor and obtained the correct output.

On reanalyzing the program I have some doubt. Please help me to get it
clarified.

The first destructor is called for the unnamed temp and not for the object
'A'. Am i correct? I had assumed the other way round, that the destructor is
called for object 'A'. So this tells me that if in case I need to reallocate
memory to the already created object it is user's responsibility to do so
(we are doing it in the assignment operator).

My question is 'Only destructors can be called explicitly and not the
constructors. So what is that I am doing in the line A= string("Praveen")?
Am I not calling the constructor explicitly here?

Thanks and Regards,
Praveen Kumar
 
K

Karl Heinz Buchegger

sahukar said:
Hello,

Thanks for the help. I added a function for assignment operator and a copy
constructor and obtained the correct output.

On reanalyzing the program I have some doubt. Please help me to get it
clarified.

The first destructor is called for the unnamed temp and not for the object
'A'. Am i correct?
Yes.

I had assumed the other way round, that the destructor is
called for object 'A'.

Why?
Destructors are called when objects go out of scope.

In

A = string("Praveen"); //explicit call

* A temporary object is created, thus it's ctor is called.
* This temporary object is passed to the assignment operator of A
* Then the statement ends and thus the temporary goes out
of scope -> dtor called for the temporary.
So this tells me that if in case I need to reallocate
memory to the already created object it is user's responsibility to do so
(we are doing it in the assignment operator).

Not sure what your question is or what the above wants to say.
My question is 'Only destructors can be called explicitly and not the
constructors. So what is that I am doing in the line A= string("Praveen")?
Am I not calling the constructor explicitly here?

No. You create an object.
Part of object creation is calling a constructor.
Get yourself into the habit of forgetting the idea of beeing able
to call a constructor (you can't). Constructors are called for you
at apropriete places - namely whenever an object comes to live and
the compiler decides which constructor it will use based on what you
specified at the point of object creation.
 
R

Rolf Magnus

sahukar said:
Hello,

Thanks for the help. I added a function for assignment operator and a
copy constructor and obtained the correct output.

On reanalyzing the program I have some doubt. Please help me to get it
clarified.

The first destructor is called for the unnamed temp and not for the
object 'A'. Am i correct?
Yes.

I had assumed the other way round, that the destructor is called for
object 'A'.

That's the second one.
So this tells me that if in case I need to reallocate memory to the
already created object it is user's responsibility to do so (we are
doing it in the assignment operator).

Why is it the user's responsibility then? The assignment operator
handles it for him.
My question is 'Only destructors can be called explicitly and not the
constructors.

It's not really an explicit destructor call either. It's a pseudo
destructor call.
So what is that I am doing in the line A=string("Praveen")? Am I not
calling the constructor explicitly here?

No. That doesn't just call the constructor, but do everything to create
the object. That object e.g. needs memory, which the constructor
doesn't supply. Note also that you are assigning its value to A, but a
constructor doesn't return any value.
The above is the same as:

string s("Praveen");
A = s;

Just with the difference that you gave the string a name and that it
doesn't go out of scope until the code block ends.
 
S

Stephen M. Webb

sahukar praveen said:
Thanks for the help. I added a function for assignment operator and a copy
constructor and obtained the correct output.

On reanalyzing the program I have some doubt. Please help me to get it
clarified.

The first destructor is called for the unnamed temp and not for the object
'A'. Am i correct? I had assumed the other way round, that the destructor is
called for object 'A'. So this tells me that if in case I need to reallocate
memory to the already created object it is user's responsibility to do so
(we are doing it in the assignment operator).

My question is 'Only destructors can be called explicitly and not the
constructors. So what is that I am doing in the line A= string("Praveen")?
Am I not calling the constructor explicitly here?

string A;
A = string("Praveen");

You are constructing a temporary object of type "string", assigning it
to the existing object A (through the operator=()) and destroying the
temporary. You could say you're invoking the constructor explicitly,
but you're also invoking the assignment operator and the destructor.
 
R

red floyd

Karl said:
But the class still contains a flaw.
The OP needs a copy constructor too.

Rule of three:

Whenever you need one of destructor, copy constructor, assignment operator
you most always need all of them.

Whoops! You're right. I misread the OP's code, and thought the constructor

string(const char *string)

was the copy constructor.

Sahukar, that's an exceptionally bad parameter name.
 
J

jeffc

sahukar praveen said:
My question is 'Only destructors can be called explicitly and not the
constructors. So what is that I am doing in the line A= string("Praveen")?
Am I not calling the constructor explicitly here?

I would not say "explicitly". I would say it's called implicitly as a "side
effect" of creating the variable. I think you'd agree that if the code
looked a little different, there would be nothing explicit about the
constructor for A being called. e.g.

class A
{};
int main()
{
A a;
}
 
S

sahukar praveen

red floyd said:
Whoops! You're right. I misread the OP's code, and thought the constructor

string(const char *string)

was the copy constructor.

Sahukar, that's an exceptionally bad parameter name.

Hello everybody,

Thanks for all the help. I could guess now what was wrong. I read some book
and as the information in the book was too less to get the overall picture I
had assumed somethings but in a wrong way. I got them cleared and also got
more info from this discussion.

Thanks and Regards,
Praveen Kumar
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,230
Latest member
LifeBoostCBD

Latest Threads

Top