0

what is the best way to design a string class constructor? The following constructors definitely have problem: two pointers pointing one object, if one of them is destructed, the other will cause a fatal error. So, what is the best way to design a constructor for a string class?

class CMyString{
    private:
        char *pData;
    public:
        CMyString(char *_p=NULL):pData(_p){
    }
        CMyString(CMyString &_str):pData((_str.pData){
    }
}
user83962
  • 85
  • 1
  • 1
  • 5

2 Answers2

2

For example you can define the class the following way.

class CMyString
{
private:
    char *pData;

public:
    CMyString( const char *_p = NULL )
    {
        if ( _p == NULL ) 
        {
            pData = NULL;
        }
        else
        {
            pData = new char[ std::strlen( _p ) + 1 ];
            std::strcpy( pData, _p );
        }
    }

    CMyString( const CMyString &_str )
    {
        if ( _str.pData == NULL ) 
        {
            pData = NULL;
        }
        else
        {
            pData = new char[ std::strlen( _str.pData ) + 1 ];
            std::strcpy( pData, _str.pData );
        }
    }

    explicit operator bool () const { return ( pData != NULL ); } 

    CMyString & operator =( const CMyString & ); // do not forget to define

    ~CMyString(); // do not forget to define
};

Or you can define the copy constructor the following way

    CMyString( const CMyString &_str ) : CMyString( _str.pData )
    {
    }
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

Allocate space and copy the characters over.

Also, I suggest not allowing pData to be null, as it complicates the logic. Instead, if no initial value is given, create an empty string.

Also, don't forget to be const-correct.

CMyString(const char *_p = "") {
    size_t len = strlen(_p);
    pData = new char[len+1];
    strcpy(pData, _p);
}
CMyString(const CMyString& _str) { /* basically the same as above */ }
Brian Bi
  • 111,498
  • 10
  • 176
  • 312
  • CMyString myStr(0); will crash this – Spock77 Feb 25 '14 at 22:44
  • I also disagree with your statement about pData to be null. It is a very real possibility that a user could indeed pass in an un-initialized char * _p, and this case should be handled. It DOES complicated the logic, but it is NECESSARY complication, when coding SAFE code. – trumpetlicks Feb 25 '14 at 22:46
  • @Alex passing in an unterminated string could also crash it. So what? You just tell your users *not to do it.* – Brian Bi Feb 25 '14 at 22:48
  • @trumpetlicks See my comment above. – Brian Bi Feb 25 '14 at 22:48
  • I prefer programs that do not crash totally when smb forget to initialize char*. Passing 0 is happening quite often. Yes, std::string does not check and will crash also. But I would prefer SafeString which checks possible errors. Why you think MS [implemented](http://msdn.microsoft.com/en-us/library/wd3wzwts.aspx) a set of *_s safe functions? They could just tell their users not to use it wrong way. But the problem is that users _do_. – Spock77 Feb 25 '14 at 23:01
  • @Alex - I whole heartedly agree, just because std does it this way does not make it right. In fact there is a large push by many software writing organizations to better their safe coding practices, and WE SHOULD on this site be helping new coders to practice the same, get in good habits!!! – trumpetlicks Feb 25 '14 at 23:04
  • @trumpetlicks - In std:: it was a design decision to make it more effective - so not to do additional checks. The point is that you can always add checks and make SafeString but not vice versa. But I would say they should include SafeString into std :). 99% cases we need simple strings which make possible checks. – Spock77 Feb 25 '14 at 23:12