What's wrong with the member function?

F

fl

Hi,
I am learning C++ with C++ primer written by Lippman. The first output
line: cout << s1 << endl; works right. The second is wrong. I find the
problem is that s1 is destroyed in the call from "result += s;". And
even though the "result" is correct in the routine:

String
String::eek:perator+( const String &s ) const
{
String result = *this;
result += s;
return result;
}

It is wrong after callback. I am not sure where is the problem.
Because it is from the book example, maybe there is some little part I
do not notice. Thank you very much.





------------
#include <string.h>
#include <assert.h>

class String {
friend ostream&
operator<<( ostream&, String& );
public:
String( const char*);
String( int );
String operator+(const String &) const;
String& operator+=(const String &);
~String();
private:
int len;
char *str;
};

String::String( const char *s)
{
len = strlen( s );
str = new char[ len + 1 ];
assert( str != 0);
strcpy(str, s );
}

String::~String()
{ delete str;
}

ostream& operator<<( ostream& os, String& str )
{
char *s = str.str;
while ( *s ) os.put( *s++ );
return os;
}

String&
String::eek:perator+=( const String &s )
{
len += s.len;
char *p = new char[len+1];
assert( p != 0);
strcpy(p,str);
strcat(p,s.str);
delete str;
str=p;
return *this;
}

String
String::eek:perator+( const String &s ) const
{
String result = *this;
result += s;
return result;
}
-----------------------
#include <iostream.h>
#include "String.h"

main()
{
String s1("gobbledy");
String s2("gook");
s1 += s2;
cout << s1 << endl;

String s3 = s1 + s2;
cout << s3 << endl;

return 0;
}
 
K

Kira Yamato

Hi,
I am learning C++ with C++ primer written by Lippman. The first output
line: cout << s1 << endl; works right. The second is wrong. I find the
problem is that s1 is destroyed in the call from "result += s;". And
even though the "result" is correct in the routine:

String
String::eek:perator+( const String &s ) const
{
String result = *this;
result += s;
return result;
}

It is wrong after callback. I am not sure where is the problem.
Because it is from the book example, maybe there is some little part I
do not notice. Thank you very much.





------------
#include <string.h>
#include <assert.h>

class String {
friend ostream&
operator<<( ostream&, String& );
public:
String( const char*);
String( int );
String operator+(const String &) const;
String& operator+=(const String &);
~String();
private:
int len;
char *str;
};

String::String( const char *s)
{
len = strlen( s );
str = new char[ len + 1 ];
assert( str != 0);
strcpy(str, s );
}

String::~String()
{ delete str;
}

ostream& operator<<( ostream& os, String& str )
{
char *s = str.str;
while ( *s ) os.put( *s++ );
return os;
}

String&
String::eek:perator+=( const String &s )
{
len += s.len;
char *p = new char[len+1];
assert( p != 0);
strcpy(p,str);
strcat(p,s.str);
delete str;
str=p;
return *this;
}

String
String::eek:perator+( const String &s ) const
{
String result = *this;
result += s;
return result;
}
-----------------------
#include <iostream.h>
#include "String.h"

main()
{
String s1("gobbledy");
String s2("gook");
s1 += s2;
cout << s1 << endl;

String s3 = s1 + s2;

What do you think the [default] copy constructor is doing in the line above?
 
F

fl

Hi,
I am learning C++ with C++ primer written by Lippman. The first output
line: cout << s1 << endl; works right. The second is wrong. I find the
problem is that s1 is destroyed in the call from "result += s;".  And
even though the "result" is correct in the routine:
String
String::eek:perator+( const String &s ) const
{
   String result = *this;
   result += s;
   return result;
}
It is wrong after callback. I am not sure where is the problem.
Because it is from the book example, maybe there is some little part I
do not notice. Thank you very much.
class String {
   friend ostream&
           operator<<( ostream&, String& );
public:
   String( const char*);
   String( int );
   String operator+(const String &) const;
   String& operator+=(const String &);
   ~String();
private:
   int len;
   char *str;
};
String::String( const char *s)
{
   len = strlen( s );
   str = new char[ len + 1 ];
   assert( str != 0);
   strcpy(str, s );
}
String::~String()
{  delete str;
}
ostream& operator<<( ostream& os, String& str )
{
   char *s = str.str;
   while ( *s ) os.put( *s++ );
   return os;
}
String&
String::eek:perator+=( const String &s )
{
   len += s.len;
   char *p = new char[len+1];
   assert( p != 0);
   strcpy(p,str);
   strcat(p,s.str);
   delete str;
   str=p;
   return *this;
}
String
String::eek:perator+( const String &s ) const
{
   String result = *this;
   result += s;
   return result;
}
main()
{
   String s1("gobbledy");
   String s2("gook");
   s1 += s2;
   cout << s1 << endl;
   String s3 = s1 + s2;

What do you think the [default] copy constructor is doing in the line above?
   cout << s3 << endl;
   return 0;
}

--

-kira- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -

You mean this:
s1 += s2;
cout << s1 << endl;

It corrects. But the book later propose the s3=s1+s2 as a new
concatenation method. From the context, it implies they can work
together (It says it uses the += operator of the previous definition).
Thanks.
 
R

Rolf Magnus

fl said:
What do you think the [default] copy constructor is doing in the line
above?
cout << s3 << endl;
return 0;
}

--

-kira- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -

You mean this:
s1 += s2;
cout << s1 << endl;

It corrects. But the book later propose the s3=s1+s2 as a new
concatenation method.

But you did not write that. You wrote:

String s3 = s1 + s2;
From the context, it implies they can work together (It says it uses the
+= operator of the previous definition).
Thanks.

Yes, but the line you wrote in your program uses the copy constructor. Since
you didn't define one, the compiler generates one for you, but in this
case, it doesn't do what you want.
The "Rule of Three" applies: If you need to write one of copy constructor,
copy assignment operator and destructor, you can be pretty certain that you
need all three of them.
 
F

fl

fl said:
What do you think the [default] copy constructor is doing in the line
above?
cout << s3 << endl;
return 0;
}
You mean this:
  s1 += s2;
  cout << s1 << endl;
It corrects. But the book later propose the s3=s1+s2 as a new
concatenation method.

But you did not write that. You wrote:

String s3 = s1 + s2;
From the context, it implies they can work together (It says it uses the
+= operator of the previous definition).
Thanks.

Yes, but the line you wrote in your program uses the copy
constructor.
Thanks. Because it is new to me, I would like to be clear with what
you mean. The follow is my new copy constructor? I see the follow is
called.

String
String::eek:perator+( const String &s ) const
{
String result = *this;
result += s;
return result;

}

And I have to write the respective assignment operator and destructor?





Since
 
F

fl

fl said:
What do you think the [default] copy constructor is doing in the line
above?
cout << s3 << endl;
return 0;
}
You mean this:
  s1 += s2;
  cout << s1 << endl;
It corrects. But the book later propose the s3=s1+s2 as a new
concatenation method.

But you did not write that. You wrote:

String s3 = s1 + s2;
From the context, it implies they can work together (It says it uses the
+= operator of the previous definition).
Thanks.

Yes, but the line you wrote in your program uses the copy constructor. Since
you didn't define one, the compiler generates one for you, but in this
case, it doesn't do what you want.
The "Rule of Three" applies: If you need to write one of copy constructor,
copy assignment operator and destructor, you can be pretty certain that you
need all three of them.- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -

Thanks to both of you. I solve it now.
 
T

Tadeusz B. Kopec

Hi,
I am learning C++ with C++ primer written by Lippman. The first output
line: cout << s1 << endl; works right. The second is wrong. I find the
problem is that s1 is destroyed in the call from "result += s;". And
even though the "result" is correct in the routine:

String
String::eek:perator+( const String &s ) const {
String result = *this;
result += s;
return result;
}

It is wrong after callback. I am not sure where is the problem. Because
it is from the book example, maybe there is some little part I do not
notice. Thank you very much.





------------
#include <string.h>
#include <assert.h>

class String {
friend ostream&
operator<<( ostream&, String& );
Are you sure the operator is going to change the String argument?
public:
String( const char*);
String( int );
String operator+(const String &) const; String& operator+=(const String
&);
~String();
private:
int len;
char *str;
};

You forgot about copy constructor (as Kira Yamato noticed)
public:
String( const String & rhs);
String::String( const char *s)
{
len = strlen( s );
str = new char[ len + 1 ];
assert( str != 0);

This will never happen. If new fails, bad_alloc is thrown.
strcpy(str, s );
}

String::~String()
{ delete str;
}

Undefined behaviour. It should be
delete[] str;
ostream& operator<<( ostream& os, String& str ) {
char *s = str.str;
while ( *s ) os.put( *s++ );
return os;
}

You don't change the str argument, so pass a const reference.
And code

os << str.str;
return os;

seems better to me
String&
String::eek:perator+=( const String &s ) {
len += s.len;
char *p = new char[len+1];
assert( p != 0);
strcpy(p,str);
strcat(p,s.str);
delete str;
str=p;
return *this;
}

String
String::eek:perator+( const String &s ) const {
String result = *this;
result += s;
return result;
}
-----------------------
#include <iostream.h>
#include "String.h"

main()
{
String s1("gobbledy");
String s2("gook");
s1 += s2;
cout << s1 << endl;

String s3 = s1 + s2;
cout << s3 << endl;

return 0;
}
 
F

fl

Hi,
I am learning C++ with C++ primer written by Lippman. The first output
line: cout << s1 << endl; works right. The second is wrong. I find the
problem is that s1 is destroyed in the call from "result += s;".  And
even though the "result" is correct in the routine:
String
String::eek:perator+( const String &s ) const {
   String result = *this;
   result += s;
   return result;
}
It is wrong after callback. I am not sure where is the problem. Because
it is from the book example, maybe there is some little part I do not
notice. Thank you very much.
class String {
   friend ostream&
           operator<<( ostream&, String& );

Are you sure the operator is going to change the String argument?


public:
   String( const char*);
   String( int );
   String operator+(const String &) const; String& operator+=(const String
   &);
   ~String();
private:
   int len;
   char *str;
};

You forgot about copy constructor (as Kira Yamato noticed)
public:
  String( const String & rhs);


String::String( const char *s)
{
   len = strlen( s );
   str = new char[ len + 1 ];
   assert( str != 0);

This will never happen. If new fails, bad_alloc is thrown.
   strcpy(str, s );
}
String::~String()
{  delete str;
}

Undefined behaviour. It should be
delete[] str;


ostream& operator<<( ostream& os, String& str ) {
   char *s = str.str;
   while ( *s ) os.put( *s++ );
   return os;
}

You don't change the str argument, so pass a const reference.
And code

    os << str.str;
    return os;

seems better to me






String&
String::eek:perator+=( const String &s ) {
   len += s.len;
   char *p = new char[len+1];
   assert( p != 0);
   strcpy(p,str);
   strcat(p,s.str);
   delete str;
   str=p;
   return *this;
}
String
String::eek:perator+( const String &s ) const {
   String result = *this;
   result += s;
   return result;
}
main()
{
   String s1("gobbledy");
   String s2("gook");
   s1 += s2;
   cout << s1 << endl;
   String s3 = s1 + s2;
   cout << s3 << endl;
   return 0;
}

--
Tadeusz B. Kopec ([email protected])
A day for firm decisions!!!!!  Or is it?- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -- Masquer le texte des messages précédents -

- Afficher le texte des messages précédents -

Thank you very much. I am really new to CPP, quite different from C.
Seems too much implicit in CPP, interesting. Happy holidays.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top