returning a &string 
Author Message
 returning a &string

Hello,

Can somebody please check if my thinking is correct.

I'm trying to return a string from a class without
making a method like getstr(char *temp);

Anyway, the code tells more than I could write...

class foo {
 private:
  char* str;

 public:

  foo(int x) {
    str = new char[0xff];  
    _itoa( x, str, 10 );
  }  

  ~foo() {
    delete str;
  }

  char& getstr(void) {
        return *str;
  }  

Quote:
};

void main()
{
        // TODO: Add extra validation here

        char* str;
        str = new char[0xff];
        foo test(1234);

        // test a return for CString
        CString cstr = &test.getstr();  

        // test return for char*
        strcpy(str, &test.getstr());        

        delete str;  

Quote:
}

I'm just not used to returning references - is this correct?


Tue, 14 Oct 2003 03:16:02 GMT  
 returning a &string

Quote:
> Hello,

> Can somebody please check if my thinking is correct.

> I'm trying to return a string from a class without
> making a method like getstr(char *temp);

> Anyway, the code tells more than I could write...

> class foo {
>  private:
>   char* str;

>  public:

>   foo(int x) {
>     str = new char[0xff];
>     _itoa( x, str, 10 );
>   }

>   ~foo() {
>     delete str;
>   }

>   char& getstr(void) {
> return *str;
>   }
> };

This returns a reference to a character. That character will be the first
character of str. You probably want to return the pointer itself, as this
will be more useful. You also want to make the thing you return const so
that it can't be messed with by the caller, and that allows you to make the
method itself const too.

const char * getstr()  const{
    return str;

Quote:
}

> void main()

This should be "int main()"

Quote:
> {
> // TODO: Add extra validation here

> char* str;
> str = new char[0xff];
> foo test(1234);

> // test a return for CString
> CString cstr = &test.getstr();

This now becomes

CString cstr = test.getstr();

Quote:

> // test return for char*
> strcpy(str, &test.getstr());

and this:

strcpy(str, test.getstr());

Quote:

>         delete str;
> }

> I'm just not used to returning references - is this correct?

Your code was "correct", but maybe not the best way to do what you wanted.

NeilB



Tue, 14 Oct 2003 02:46:07 GMT  
 returning a &string
standard "C strings" are just character pointers.  To do basically what you
want you need a "reference to a pointer to a character", however, that's
really not necessary and overkill.  What you have was a "reference to a
character"...just a single character...not what you want.

Just do this, if this is what you want:

class foo {
 private:
  char* str;

 public:

  foo(int x) {
    str = new char[0xff];
    _itoa( x, str, 10 );
  }

  ~foo() {
    delete str;
  }

  const char* getstr(void) {
return str;
  }

Quote:
};

void main()
{
// TODO: Add extra validation here

char* str;
str = new char[0xff];
foo test(1234);

// test a return for CString
CString cstr = test.getstr();

// test return for char*
strcpy(str, test.getstr());

        delete str;

Quote:
}

Some notes:

1.  You should protect the copy constructor for this class or "bad things
will happen".

2.  You might want to consider the STL string class instead.  It probably
will make your life easier.

3.  If you ever want to port this class to, say, unix, dump the nonstandard
itoa function and use "sprintf" instead. e.g.

  foo(int x) {
    str = new char[0xff];
    sprintf(str,"%ld",x);
  }

4.  The getstr method should probably be const so that you can use const
versions of the class w/o issue:

  const char* getstr(void) const {
return str;
  }

// ...

const foo test2(1234);

strcpy(str, test2.getstr());

--
Reginald Blue                   | Opinions expressed here do not
Natural Language Understanding  | necessarily represent those of
Unisys Corporation              | my employer.
--------------------------------+-------------------------------

NL technology,speech application| My email address is wrong, you
development training, see:      | need to remove the obvious.
http://www.speechdepot.com/     +-------------------------------


Quote:
> Hello,

> Can somebody please check if my thinking is correct.

> I'm trying to return a string from a class without
> making a method like getstr(char *temp);

> Anyway, the code tells more than I could write...

> class foo {
>  private:
>   char* str;

>  public:

>   foo(int x) {
>     str = new char[0xff];
>     _itoa( x, str, 10 );
>   }

>   ~foo() {
>     delete str;
>   }

>   char& getstr(void) {
> return *str;
>   }
> };

> void main()
> {
> // TODO: Add extra validation here

> char* str;
> str = new char[0xff];
> foo test(1234);

> // test a return for CString
> CString cstr = &test.getstr();

> // test return for char*
> strcpy(str, &test.getstr());

>         delete str;
> }

> I'm just not used to returning references - is this correct?



Tue, 14 Oct 2003 03:29:31 GMT  
 returning a &string
Hello,

Thanks for responding.  I really appreciate your time.
I hope you don't mind, but I have one more question
regarding returning strings.  I need to add one line
of code that might help you understand what I trying
to do.  basically the operator::= will not let me
return a (const char*).. It seems to be working, but
again, I leary if I'm doing it right!  EX:

foo test(1234);
CString cstr2 = test;  
test = "HI";

(obviously I need to do some overloading)

class foo {
 private:
  char* str;

 public:
  foo(char* tstr) {
    str = new char[0xff];  
        strcpy(str, tstr);
  }

  foo(int x) {
    str = new char[0xff];  
    _itoa( x, str, 10 );
  }  

  ~foo() { delete str; }

  const char* getstr(void) {
        return str;
  }  

  foo& operator = (char* tstr)
  {
    strcpy(str,tstr);
        return *this;                    
  };

  operator char*()
  {
     return str;
  }

Quote:
};

void CStrTestDlg::OnOK()
{
        // TODO: Add extra validation here

        char* str;
        str = new char[0xff];
        foo test(1234);

        // test a return for CString
        CString cstr1 = test.getstr();  

                // test overload = operator
        CString cstr2 = test;  
        test = "0987";

        // test return of char*
        strcpy(str, test.getstr());    

        CDialog::OnOK();

Quote:
}

Well, I hope I attached enough info.  A simple push in the right
direction would help a lot.  

Thanks in advance.  And thanks for your time!

Quote:
-----Original Message-----

standard "C strings" are just character pointers.  To do basically what you
want you need a "reference to a pointer to a character", however, that's
really not necessary and overkill.  What you have was a "reference to a
character"...just a single character...not what you want.

Just do this, if this is what you want:

class foo {
 private:
  char* str;

 public:

  foo(int x) {
    str = new char[0xff];
    _itoa( x, str, 10 );
  }

  ~foo() {
    delete str;
  }

  const char* getstr(void) {
return str;
  }
};

void main()
{
// TODO: Add extra validation here

char* str;
str = new char[0xff];
foo test(1234);

// test a return for CString
CString cstr = test.getstr();

// test return for char*
strcpy(str, test.getstr());

        delete str;
}

Some notes:

1.  You should protect the copy constructor for this class or "bad things
will happen".

2.  You might want to consider the STL string class instead.  It probably
will make your life easier.

3.  If you ever want to port this class to, say, unix, dump the nonstandard
itoa function and use "sprintf" instead. e.g.

  foo(int x) {
    str = new char[0xff];
    sprintf(str,"%ld",x);
  }

4.  The getstr method should probably be const so that you can use const
versions of the class w/o issue:

  const char* getstr(void) const {
return str;
  }

// ...

const foo test2(1234);

strcpy(str, test2.getstr());

--
Reginald Blue                   | Opinions expressed here do not
Natural Language Understanding  | necessarily represent those of
Unisys Corporation              | my employer.
--------------------------------+-------------------------------

NL technology,speech application| My email address is wrong, you
development training, see:      | need to remove the obvious.
http://www.speechdepot.com/     +-------------------------------



> Hello,

> Can somebody please check if my thinking is correct.

> I'm trying to return a string from a class without
> making a method like getstr(char *temp);

> Anyway, the code tells more than I could write...

> class foo {
>  private:
>   char* str;

>  public:

>   foo(int x) {
>     str = new char[0xff];
>     _itoa( x, str, 10 );
>   }

>   ~foo() {
>     delete str;
>   }

>   char& getstr(void) {
> return *str;
>   }
> };

> void main()
> {
> // TODO: Add extra validation here

> char* str;
> str = new char[0xff];
> foo test(1234);

> // test a return for CString
> CString cstr = &test.getstr();

> // test return for char*
> strcpy(str, &test.getstr());

>         delete str;
> }

> I'm just not used to returning references - is this correct?

.



Tue, 14 Oct 2003 05:01:47 GMT  
 returning a &string
BTW, I missed the void main that Neil caught.  Yes, you want:

int main(void)

-- below...

Oh, and one final thing:

You haven't protected the default constructor.  If you default construct
this, "str" will contain random data...when it's deleted in the destructor,
BOOM!  Either make it private or make it a "empty string" or something.

--
Reginald Blue                   | Opinions expressed here do not
Natural Language Understanding  | necessarily represent those of
Unisys Corporation              | my employer.
--------------------------------+-------------------------------

NL technology,speech application| My email address is wrong, you
development training, see:      | need to remove the obvious.
http://www.speechdepot.com/     +-------------------------------


Quote:
> Hello,

> Thanks for responding.  I really appreciate your time.
> I hope you don't mind, but I have one more question
> regarding returning strings.  I need to add one line
> of code that might help you understand what I trying
> to do.  basically the operator::= will not let me
> return a (const char*).. It seems to be working, but
> again, I leary if I'm doing it right!  EX:

> foo test(1234);
> CString cstr2 = test;
> test = "HI";

> (obviously I need to do some overloading)

> class foo {
>  private:
>   char* str;

>  public:
>   foo(char* tstr) {
>     str = new char[0xff];
> strcpy(str, tstr);
>   }

>   foo(int x) {
>     str = new char[0xff];
>     _itoa( x, str, 10 );
>   }

>   ~foo() { delete str; }

>   const char* getstr(void) {
> return str;
>   }

>   foo& operator = (char* tstr)
>   {
>     strcpy(str,tstr);
> return *this;
>   };

-- ARG!!!  You haven't ensured that str is large enough to hold what you're
passed.  If it isn't, then BOOM, you'll damage the heap.

-- You really ought to consider using one of the STL classes, but if you
REALLY want to do this, here's a quick hack:

  foo& operator = (char* tstr)
  {
    delete [] str;
    str = new char[strlen(tstr)+1];
    strcpy(str,tstr);
return *this;
  };

-- Inefficient because it _might_ be big enough already, but always safe.
NOTE::that code is untested.  I think that's right though...(someone will
nail me if I goofed it.)

Quote:
>   operator char*()
>   {
>      return str;
>   }

-- bad for similar reasons as before.  You really don't want someone mucking
with your memory so:

  operator const char*()
  {
     return str;
  }

-- Also, generally avoid doing this kind of thing.  Yeah, I know, it's awful
convenient...that is until you accidentally use your class where you
shouldn't and it converts it to a const char * "because it thought that's
what you meant."  Makes tracking down bugs awfully difficult at times.  Your
"getstr" method is perfect.

- Show quoted text -

Quote:
> };

> void CStrTestDlg::OnOK()
> {
> // TODO: Add extra validation here

> char* str;
> str = new char[0xff];
> foo test(1234);

> // test a return for CString
> CString cstr1 = test.getstr();

>         // test overload = operator
> CString cstr2 = test;
> test = "0987";

> // test return of char*
> strcpy(str, test.getstr());

> CDialog::OnOK();
> }



Tue, 14 Oct 2003 05:22:52 GMT  
 returning a &string
First of all you should definitely not reserve all that memory at
construction time for your string but instead reserve what is needed, like:

foo(char* tstr)
{
    str = new char[strlen(tstr) + 1];
    strcpy(str, tstr);

Quote:
}

Then there are some problems with your operator=.  It should probably be
modified to something like:

foo& operator = (char* tstr)
{
    delete [] str;
    str = new char[strlen(tstr) + 1];
    strcpy(str,tstr);
    return *this;

Quote:
};

You have to delete str first since tstr probably is not of the same size as
str.
Your char* conversion operator also gives way to corruption of foos
internal data because it is not declared to
return a const char*, hence I can do anything I like with your private
members memory like:

foo str("string");
char* pStr = str;
delete pStr;          // deletes memory pointed to by both pStr and str :(
Declare this operator const char* so your internal data is encapsulated
properly.
Yet another thing here is your destructor.  It must delete the char*
correctly like:

~foo() { delete [] str; }

There are lots of good C++ books that cover these kinds of topics and I
suggest you get your hands on one of those, for example:
"The C++ Programming Language, Special Edition" by Bjarne Stroustrup,
"Effective C++" and "More Effective C++" by Scott Meyers, and
"C++ Primer" by Stanley B. Lippman and Josee Lajoie.

Hope that helps :)


Hello,

Thanks for responding.  I really appreciate your time.
I hope you don't mind, but I have one more question
regarding returning strings.  I need to add one line
of code that might help you understand what I trying
to do.  basically the operator::= will not let me
return a (const char*).. It seems to be working, but
again, I leary if I'm doing it right!  EX:

foo test(1234);
CString cstr2 = test;
test = "HI";

(obviously I need to do some overloading)

class foo {
 private:
  char* str;

 public:
  foo(char* tstr) {
    str = new char[0xff];
strcpy(str, tstr);
  }

  foo(int x) {
    str = new char[0xff];
    _itoa( x, str, 10 );
  }

  ~foo() { delete str; }

  const char* getstr(void) {
return str;
  }

  foo& operator = (char* tstr)
  {
    strcpy(str,tstr);
return *this;
  };

  operator char*()
  {
     return str;
  }

Quote:
};

void CStrTestDlg::OnOK()
{
// TODO: Add extra validation here

char* str;
str = new char[0xff];
foo test(1234);

// test a return for CString
CString cstr1 = test.getstr();

        // test overload = operator
CString cstr2 = test;
test = "0987";

// test return of char*
strcpy(str, test.getstr());

CDialog::OnOK();

Quote:
}

Well, I hope I attached enough info.  A simple push in the right
direction would help a lot.

Thanks in advance.  And thanks for your time!

Quote:
-----Original Message-----

standard "C strings" are just character pointers.  To do basically what you
want you need a "reference to a pointer to a character", however, that's
really not necessary and overkill.  What you have was a "reference to a
character"...just a single character...not what you want.

Just do this, if this is what you want:

class foo {
 private:
  char* str;

 public:

  foo(int x) {
    str = new char[0xff];
    _itoa( x, str, 10 );
  }

  ~foo() {
    delete str;
  }

  const char* getstr(void) {
return str;
  }
};

void main()
{
// TODO: Add extra validation here

char* str;
str = new char[0xff];
foo test(1234);

// test a return for CString
CString cstr = test.getstr();

// test return for char*
strcpy(str, test.getstr());

        delete str;
}

Some notes:

1.  You should protect the copy constructor for this class or "bad things
will happen".

2.  You might want to consider the STL string class instead.  It probably
will make your life easier.

3.  If you ever want to port this class to, say, unix, dump the nonstandard
itoa function and use "sprintf" instead. e.g.

  foo(int x) {
    str = new char[0xff];
    sprintf(str,"%ld",x);
  }

4.  The getstr method should probably be const so that you can use const
versions of the class w/o issue:

  const char* getstr(void) const {
return str;
  }

// ...

const foo test2(1234);

strcpy(str, test2.getstr());

--
Reginald Blue                   | Opinions expressed here do not
Natural Language Understanding  | necessarily represent those of
Unisys Corporation              | my employer.
--------------------------------+-------------------------------

NL technology,speech application| My email address is wrong, you
development training, see:      | need to remove the obvious.
http://www.speechdepot.com/     +-------------------------------



> Hello,

> Can somebody please check if my thinking is correct.

> I'm trying to return a string from a class without
> making a method like getstr(char *temp);

> Anyway, the code tells more than I could write...

> class foo {
>  private:
>   char* str;

>  public:

>   foo(int x) {
>     str = new char[0xff];
>     _itoa( x, str, 10 );
>   }

>   ~foo() {
>     delete str;
>   }

>   char& getstr(void) {
> return *str;
>   }
> };

> void main()
> {
> // TODO: Add extra validation here

> char* str;
> str = new char[0xff];
> foo test(1234);

> // test a return for CString
> CString cstr = &test.getstr();

> // test return for char*
> strcpy(str, &test.getstr());

>         delete str;
> }

> I'm just not used to returning references - is this correct?

.



Tue, 14 Oct 2003 18:13:05 GMT  
 returning a &string

foo& operator = (char* tstr)
{
    if(str == tstr)   //always add check to
        return *this; // make sure you don't delete str
    delete [] str;
    str = new char[strlen(tstr) + 1];
    strcpy(str,tstr);
    return *this;

Quote:
};

M

  First of all you should definitely not reserve all that memory at
  construction time for your string but instead reserve what is needed,
like:

  foo(char* tstr)
  {
      str = new char[strlen(tstr) + 1];
      strcpy(str, tstr);
  }

  Then there are some problems with your operator=.  It should probably be
  modified to something like:

  foo& operator = (char* tstr)
  {
      delete [] str;
      str = new char[strlen(tstr) + 1];
      strcpy(str,tstr);
      return *this;
  };

  You have to delete str first since tstr probably is not of the same size
as
  str.
  Your char* conversion operator also gives way to corruption of foos
  internal data because it is not declared to
  return a const char*, hence I can do anything I like with your private
  members memory like:

  <snip>



Thu, 16 Oct 2003 15:15:03 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. getline(istream&,string&) double return

2. Return string or string&

3. passing character strings to functions with return string

4. Help about string & sub-string

5. HELP:Files && Quoted Strings

6. Fread returns 0, ferror returns 0, feof returns 16

7. signal & sigvec error return codes

8. (void *) & casting the pointer returned by malloc

9. Select returning UPPER & LOWER CASE

10. microsoft access & odbc, returning uniqe numbers

11. Help needed: ClistCtrl & Return Key

12. partial template specialization & covariant returns

 

 
Powered by phpBB® Forum Software