design question

Discussion in 'C++' started by Shea Martin, Aug 20, 2004.

  1. Shea Martin

    Shea Martin Guest

    I have a MyString class:
    class MyString
    {
    public:
    MyString() {}
    MyString(const char *str)
    {
    _buffer = new char[strlen(str)+1];
    strcpy(_buffer, str);
    }

    void func1(const MyString &str)
    {
    printf("str is %s\n", str._buffer);
    }

    private:
    char *_buffer;
    };

    Passing func1 a const char *, will result in a deep copy occurring. Because str
    is const, the deep copy is not necessary. Obviously I can't have my conversion
    constructor do a shallow copy, unless I know the created object is const.

    It there a way to differentiate whether a constructor is creating a const object
    or not?

    i.e.,

    class MyString
    {
    public:
    MyString() {}
    MyString(const char *str)
    {
    _buffer = new char[strlen(str)+1];
    strcpy(_buffer, str);
    }
    const MyString(const char *str)
    {
    _buffer = (char*)str;
    }

    void func1(const MyString &str)
    {
    printf("str is %s\n", str._buffer);
    }

    private:
    char *_buffer;
    };


    Obviously this syntax won't work, but you get the idea of what I am trying to
    accomplish.

    Thanks,

    ~Shea M.
    Shea Martin, Aug 20, 2004
    #1
    1. Advertising

  2. Shea Martin wrote:
    > I have a MyString class:
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    > Passing func1 a const char *, will result in a deep copy occurring.
    > Because str is const, the deep copy is not necessary.


    Apparently, a copy is not necessary at all. So, why not just overload
    the 'func1' and have the second version accept const char* ?


    > Obviously I can't
    > have my conversion constructor do a shallow copy, unless I know the
    > created object is const.
    >
    > It there a way to differentiate whether a constructor is creating a
    > const object or not?


    No.

    > [..]


    V
    Victor Bazarov, Aug 20, 2004
    #2
    1. Advertising

  3. Shea Martin

    David Hilsee Guest

    "Shea Martin" <> wrote in message
    news:...
    > I have a MyString class:
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    > Passing func1 a const char *, will result in a deep copy occurring.

    Because str
    > is const, the deep copy is not necessary. Obviously I can't have my

    conversion
    > constructor do a shallow copy, unless I know the created object is const.
    >
    > It there a way to differentiate whether a constructor is creating a const

    object
    > or not?
    >
    > i.e.,
    >
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    > const MyString(const char *str)
    > {
    > _buffer = (char*)str;
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    >
    > Obviously this syntax won't work, but you get the idea of what I am trying

    to
    > accomplish.


    I think you are misunderstanding what const means. Most objects that exist
    in a C++ program are not const. When they are passed to functions, they may
    be passed by reference-to-const or pointer-to-const, but that does not mean
    that the original object is const. It just means that the function will not
    modify the object (at least, not without some casting). Example:

    char buffer[] = "foo";
    const MyString myStr(buffer);

    // if no deep copy is made, then the following makes func1
    // display "boo" instead of "foo" (once func1 is made const)
    buffer[0] = 'b';

    Besides that, there are object lifetime issues to consider. The original
    array could have a shorter lifetime than the MyString instance. I think you
    should perform a deep copy.

    --
    David Hilsee
    David Hilsee, Aug 20, 2004
    #3
  4. Shea Martin

    Shea Martin Guest

    Victor Bazarov wrote:
    > Shea Martin wrote:
    >
    >> I have a MyString class:
    >> class MyString
    >> {
    >> public:
    >> MyString() {}
    >> MyString(const char *str)
    >> {
    >> _buffer = new char[strlen(str)+1];
    >> strcpy(_buffer, str);
    >> }
    >>
    >> void func1(const MyString &str)
    >> {
    >> printf("str is %s\n", str._buffer);
    >> }
    >>
    >> private:
    >> char *_buffer;
    >> };
    >>
    >> Passing func1 a const char *, will result in a deep copy occurring.
    >> Because str is const, the deep copy is not necessary.

    >
    >
    > Apparently, a copy is not necessary at all. So, why not just overload
    > the 'func1' and have the second version accept const char* ?

    That is what I currently do (with a couple of shortcuts). This is easy for just
    func1(), but a PIA for funcN()...func99(). I was just hoping there was a more
    elegant way of doing it.

    Thanks,

    ~S
    >
    >
    > > Obviously I can't

    >
    >> have my conversion constructor do a shallow copy, unless I know the
    >> created object is const.
    >>
    >> It there a way to differentiate whether a constructor is creating a
    >> const object or not?

    >
    >
    > No.
    >
    >> [..]

    >
    >
    > V
    Shea Martin, Aug 20, 2004
    #4
  5. Shea Martin

    Shea Martin Guest

    David Hilsee wrote:
    > "Shea Martin" <> wrote in message
    > news:...
    >
    >>I have a MyString class:
    >>class MyString
    >>{
    >> public:
    >> MyString() {}
    >> MyString(const char *str)
    >> {
    >> _buffer = new char[strlen(str)+1];
    >> strcpy(_buffer, str);
    >> }
    >>
    >> void func1(const MyString &str)
    >> {
    >> printf("str is %s\n", str._buffer);
    >> }
    >>
    >> private:
    >> char *_buffer;
    >>};
    >>
    >>Passing func1 a const char *, will result in a deep copy occurring.

    >
    > Because str
    >
    >>is const, the deep copy is not necessary. Obviously I can't have my

    >
    > conversion
    >
    >>constructor do a shallow copy, unless I know the created object is const.
    >>
    >>It there a way to differentiate whether a constructor is creating a const

    >
    > object
    >
    >>or not?
    >>
    >>i.e.,
    >>
    >>class MyString
    >>{
    >> public:
    >> MyString() {}
    >> MyString(const char *str)
    >> {
    >> _buffer = new char[strlen(str)+1];
    >> strcpy(_buffer, str);
    >> }
    >> const MyString(const char *str)
    >> {
    >> _buffer = (char*)str;
    >> }
    >>
    >> void func1(const MyString &str)
    >> {
    >> printf("str is %s\n", str._buffer);
    >> }
    >>
    >> private:
    >> char *_buffer;
    >>};
    >>
    >>
    >>Obviously this syntax won't work, but you get the idea of what I am trying

    >
    > to
    >
    >>accomplish.

    >
    >
    > I think you are misunderstanding what const means. Most objects that exist
    > in a C++ program are not const. When they are passed to functions, they may
    > be passed by reference-to-const or pointer-to-const, but that does not mean
    > that the original object is const. It just means that the function will not
    > modify the object (at least, not without some casting). Example:
    >
    > char buffer[] = "foo";
    > const MyString myStr(buffer);
    >
    > // if no deep copy is made, then the following makes func1
    > // display "boo" instead of "foo" (once func1 is made const)
    > buffer[0] = 'b';
    >
    > Besides that, there are object lifetime issues to consider. The original
    > array could have a shorter lifetime than the MyString instance. I think you
    > should perform a deep copy.
    >


    I realize the danger of shallow copies, I was just hoping that there might way
    to save a deep copy, when I don't need it (without overloading).

    ~S
    Shea Martin, Aug 20, 2004
    #5
  6. Shea Martin

    David Hilsee Guest

    "Shea Martin" <> wrote in message
    news:...
    <snip>
    > I realize the danger of shallow copies, I was just hoping that there might

    way
    > to save a deep copy, when I don't need it (without overloading).


    Are you concerned about performance? For a string class, I would bet that
    the overhead of dynamically allocating the array has more of an adverse
    impact on performance than the actual copy. You could run some tests to
    determine what is the problem. If there is a performance problem with the
    dynamic allocation, have you considered using the old trick where a
    fixed-width buffer is used for smaller strings and a dynamically-allocated
    one is used for larger strings? It might result in cleaner code and more
    efficient behavior for the (usually common) smaller strings. Some
    std::string implementations (Dinkumware's?) do this.

    If you wanted to avoid a deep copy, you could pass an extra "bool
    doDeepCopy" to the constructor and cross your fingers that you always
    specify the right value, but that could get tricky.

    --
    David Hilsee
    David Hilsee, Aug 20, 2004
    #6
  7. * Shea Martin:
    >
    > I have a MyString class:
    >
    > class MyString
    > {


    private:

    MyString( MyString const& );
    MyString& operator=( MyString const& );


    > public:
    > MyString() {}


    Uh oh,

    Mystring(): buffer_( 0 ) {}


    > MyString(const char *str)


    MyString( char const* str ): buffer_( 0 )

    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }


    Uh oh,

    ~MyString() { delete buffer_; }

    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    > Passing func1 a const char *, will result in a deep copy occurring.


    You mean, an instantiation, not a deep copy.


    > Because str is const, the deep copy is not necessary.


    You mean, because func1 is your own function where you control the
    argument type, an instantiation of MyString is not necessary.


    > Obviously I can't have my conversion
    > constructor do a shallow copy, unless I know the created object is const.


    You mean, obviously you cannot let your MyString object refer directly to
    the client code's char const* pointer unless you know that that character
    array will exist for the duration of the MyString object's lifetime, and
    furthermore you cannot do things efficiently and be const correct etc.
    unless you know that it will also be unchanging during that time.


    > It there a way to differentiate whether a constructor is creating a const object
    > or not?


    You mean, is there a way to differentiate whether a char const* pointer
    passed as actual argument to a MyString constructor points to a character
    array that will exist and be unchanging for the duration of the MyString
    object?

    Yes, you can impose that as a requirement on client code.

    But other than that, no.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Aug 20, 2004
    #7
  8. Shea Martin

    Daniel T. Guest

    Shea Martin <> wrote:

    > I have a MyString class:
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    > Passing func1 a const char *, will result in a deep copy occurring. Because
    > str
    > is const, the deep copy is not necessary. Obviously I can't have my
    > conversion
    > constructor do a shallow copy, unless I know the created object is const.


    How about this:

    class MyString {
    char* _buffer;
    public:
    // the basic stuff, just to show how it's done...
    MyString(): _buffer( 0 ) { }
    MyString( const char* c ):
    _buffer( c ? new char[strlen( c ) + 1] : 0 ) {
    if ( _buffer ) strcpy( _buffer, c );
    }
    MyString( const MyString& s ):
    _buffer( s._buffer ? new char[strlen( s._buffer ) + 1] : 0 ) {
    if ( _buffer ) strcpy( _buffer, s._buffer );
    }
    ~MyString() { delete [] _buffer; }
    MyString& operator=( const MyString& s ) {
    char* c = s._buffer ? new char[strlen( s._buffer ) + 1] : 0;
    if ( c ) strcpy( c, s._buffer );
    delete [] _buffer;
    _buffer = c;
    }

    // what you seem to be asking about...
    static void func1( const char* str ) {
    printf( "str is %s\n", str );
    }

    static void func1( const MyString& str ) {
    printf( "str is %s\n", str._buffer );
    }
    };

    A couple of points. 'func1' is made static because it doesn't use the
    'this' pointer. The first version 'func1(const char*)' will be called
    for string literals or other char pointers, while the second version
    will be called for MyString objects.

    > It there a way to differentiate whether a constructor is creating a const
    > object or not?


    No.

    > Obviously this syntax won't work, but you get the idea of what I am trying to
    > accomplish.


    You can't do what you are trying to accomplish (assuming I get it.)
    There is no way to know for sure if a particular 'const char*' is
    pointing to a string literal or not. It may be pointing to a auto char[]
    or a dynamically allocated block...
    Daniel T., Aug 21, 2004
    #8
  9. Shea Martin

    Anil Mamede Guest

    On Fri, 20 Aug 2004 14:10:39 -0600, Shea Martin wrote:

    > I have a MyString class:
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }


    void func1(const char* str)
    {
    printf("str is %s\n", str);
    }




    >
    > private:
    > char *_buffer;
    > };
    >
    > Passing func1 a const char *, will result in a deep copy occurring. Because str
    > is const, the deep copy is not necessary. Obviously I can't have my conversion
    > constructor do a shallow copy, unless I know the created object is const.
    >



    Anil Mamede
    Anil Mamede, Aug 21, 2004
    #9
  10. Shea Martin wrote:

    > It there a way to differentiate whether a constructor is creating a
    > const object or not?
    >
    > i.e.,
    >
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    > const MyString(const char *str)
    > {
    > _buffer = (char*)str;
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    >
    > Obviously this syntax won't work, but you get the idea of what I am
    > trying to accomplish.



    There are many ways. E.g.

    class MyString
    {
    char *buffer;
    const char *buffer;
    bool shallowed;


    public:

    MyString(const char *str, bool shallow=false)
    {
    shallowed=shallow;

    if(shallow)
    const_buffer=str;

    else
    {
    buffer=new new char[strlen(str)+1];
    // ...
    }
    }

    // ...
    };



    However the whole design doesn't look good. You have func1() as a member
    function, etc.


    Not to mention why you bother to define your string class, while there
    is std::string.






    Regards,

    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Aug 21, 2004
    #10
  11. Ioannis Vranos wrote:


    Some stupid mistakes fixed:



    > There are many ways. E.g.


    class MyString
    {
    char *buffer;
    const char *const_buffer;
    bool shallowed;


    public:

    MyString(const char *str, bool shallow=false)
    {
    shallowed=shallow;

    if(shallow)
    const_buffer=str;

    else
    {
    buffer=new char[strlen(str)+1];
    // ...
    }
    }

    // ...
    };



    > However the whole design doesn't look good. You have func1() as a member
    > function, etc.
    >
    >
    > Not to mention why you bother to define your string class, while there
    > is std::string.







    Regards,

    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Aug 21, 2004
    #11
  12. Shea Martin

    Rich Grise Guest

    Shea Martin wrote:

    > I have a MyString class:

    ....
    > Passing func1 a const char *, will result in a deep copy occurring.
    > Because str is const, the deep copy is not necessary. Obviously I can't
    > have my conversion constructor do a shallow copy, unless I know the
    > created object is const.


    Pardon me for butting in, but I've scanned the first four C++ glossaries at
    http://www.google.com/search?hl=en&ie=ISO-8859-1&q=+c++ +glossary&btnG=Google Search

    and haven't found "deep copy". Or "deep" anything, for that matter. What
    does it mean?

    Thanks,
    Rich
    Rich Grise, Aug 21, 2004
    #12
  13. Shea Martin

    Daniel T. Guest

    In article <ZyPVc.5048$>,
    Rich Grise <> wrote:

    > Shea Martin wrote:
    >
    > > I have a MyString class:

    > ...
    > > Passing func1 a const char *, will result in a deep copy occurring.
    > > Because str is const, the deep copy is not necessary. Obviously I can't
    > > have my conversion constructor do a shallow copy, unless I know the
    > > created object is const.

    >
    > Pardon me for butting in, but I've scanned the first four C++ glossaries at
    > http://www.google.com/search?hl=en&ie=ISO-8859-1&q=+c++ +glossary&btnG
    > =Google+Search
    >
    > and haven't found "deep copy". Or "deep" anything, for that matter. What
    > does it mean?


    class Shallow {
    char* buf;
    public:
    Shallow( char* b ): buf( b ) { }
    Shallow( const Shallow& other ): buf( other.buf ) { }
    ~Shallow() {
    // the block of memory pointed to by 'buf' might be shared,
    // so we can't risk deleting it
    }
    Shallow& operator=( const Shallow& other ) {
    buf = other.buf;
    return *this;
    }
    };

    class Deep {
    char* buf;
    public:
    Deep( const char* b ): buf( 0 ) {
    if ( b ) {
    buf = new char[strlen( b ) + 1];
    strcpy( buf, b );
    }
    }
    Deep( const Deep& other ): buf( 0 ) {
    if ( other.buf ) {
    buf = new char[strlen( b ) + 1];
    strcpy( buf, other.buf );
    }
    }
    ~Deep() {
    delete [] buf; // we can delete here because we know that
    // no other code is using the memory
    }
    Deep& operator=( const Deep& other ) {
    char* temp = 0;
    if ( other.buf ) {
    temp = new char[strlen( b ) + 1];
    strcpy( temp, other.buf );
    }
    swap( buf, temp );
    delete [] temp;
    return *this;
    }
    };

    (Quick note, there is a lot of needless duplication in 'Deep' above that
    was left in so that people less skilled in the language would find it
    easier to follow. Make it an exorcise to remove as much duplication as
    possible.)

    Examine the two classes above, when you understand them, you will
    understand the difference between shallow and deep copy...
    Daniel T., Aug 22, 2004
    #13
  14. Shea Martin

    Shea Martin Guest

    David Hilsee wrote:
    > "Shea Martin" <> wrote in message
    > news:...
    > <snip>
    >
    >>I realize the danger of shallow copies, I was just hoping that there might

    >
    > way
    >
    >>to save a deep copy, when I don't need it (without overloading).

    >
    >
    > Are you concerned about performance? For a string class, I would bet that
    > the overhead of dynamically allocating the array has more of an adverse
    > impact on performance than the actual copy. You could run some tests to
    > determine what is the problem. If there is a performance problem with the
    > dynamic allocation, have you considered using the old trick where a
    > fixed-width buffer is used for smaller strings and a dynamically-allocated
    > one is used for larger strings? It might result in cleaner code and more
    > efficient behavior for the (usually common) smaller strings. Some
    > std::string implementations (Dinkumware's?) do this.
    >
    > If you wanted to avoid a deep copy, you could pass an extra "bool
    > doDeepCopy" to the constructor and cross your fingers that you always
    > specify the right value, but that could get tricky.
    >

    I use a plus or minus system: when allocating I always allocate the amount I
    need plus a little more. I also don't bother to shrink my buffer unless the
    length of the string varies from the buffer size by a certain threshold.

    I realize that the allocate is much slower than the copy. That is why a shallow
    copy in certain situations is would avoid an array allocation all together.

    Actually what I do now, is have a private method called setBuffer. When a const
    char is passed, and I know I won't be altering its contents, I assign the const
    char array to the char array member of the string class, and call the same
    method using the newly created string. While this approach still requires
    overloading, at least it lets me put all my logic in one method instead of doing
    copy paste. I still don't really like this method, as it makes me feel dirty.

    ~S
    Shea Martin, Aug 23, 2004
    #14
  15. Shea Martin

    Shea Martin Guest

    Alf P. Steinbach wrote:
    > * Shea Martin:
    >
    >>I have a MyString class:
    >>
    >>class MyString
    >>{

    >
    >
    > private:
    >
    > MyString( MyString const& );
    > MyString& operator=( MyString const& );
    >
    >
    >
    >> public:
    >> MyString() {}

    >
    >
    > Uh oh,
    >
    > Mystring(): buffer_( 0 ) {}
    >
    >
    >
    >> MyString(const char *str)

    >
    >
    > MyString( char const* str ): buffer_( 0 )
    >
    >
    >> {
    >> _buffer = new char[strlen(str)+1];
    >> strcpy(_buffer, str);
    >> }

    >
    >
    > Uh oh,
    >
    > ~MyString() { delete buffer_; }
    >
    >
    >> void func1(const MyString &str)
    >> {
    >> printf("str is %s\n", str._buffer);
    >> }
    >>
    >> private:
    >> char *_buffer;
    >>};
    >>
    >>Passing func1 a const char *, will result in a deep copy occurring.

    >
    >
    > You mean, an instantiation, not a deep copy.
    >
    >
    >
    >>Because str is const, the deep copy is not necessary.

    >
    >
    > You mean, because func1 is your own function where you control the
    > argument type, an instantiation of MyString is not necessary.
    >
    >
    >
    >>Obviously I can't have my conversion
    >>constructor do a shallow copy, unless I know the created object is const.

    >
    >
    > You mean, obviously you cannot let your MyString object refer directly to
    > the client code's char const* pointer unless you know that that character
    > array will exist for the duration of the MyString object's lifetime, and
    > furthermore you cannot do things efficiently and be const correct etc.
    > unless you know that it will also be unchanging during that time.


    Because func1 is my code, I know that I will only be using the const char * for
    the duration of the func1 call, and as read-only. So I in a single threaded
    environment, I can consider the call to func1 atomic, so I know I will be OK.
    Basically I was looking for a way to cheat, and the resounding answer seems to
    be don't cheat.

    ~S

    >
    >
    >
    >>It there a way to differentiate whether a constructor is creating a const object
    >>or not?

    >
    >
    > You mean, is there a way to differentiate whether a char const* pointer
    > passed as actual argument to a MyString constructor points to a character
    > array that will exist and be unchanging for the duration of the MyString
    > object?
    >
    > Yes, you can impose that as a requirement on client code.
    >
    > But other than that, no.
    >
    Shea Martin, Aug 23, 2004
    #15
  16. Shea Martin

    Shea Martin Guest

    Ioannis Vranos wrote:
    > Shea Martin wrote:
    >
    >> It there a way to differentiate whether a constructor is creating a
    >> const object or not?
    >>
    >> i.e.,
    >>
    >> class MyString
    >> {
    >> public:
    >> MyString() {}
    >> MyString(const char *str)
    >> {
    >> _buffer = new char[strlen(str)+1];
    >> strcpy(_buffer, str);
    >> }
    >> const MyString(const char *str)
    >> {
    >> _buffer = (char*)str;
    >> }
    >>
    >> void func1(const MyString &str)
    >> {
    >> printf("str is %s\n", str._buffer);
    >> }
    >>
    >> private:
    >> char *_buffer;
    >> };
    >>
    >>
    >> Obviously this syntax won't work, but you get the idea of what I am
    >> trying to accomplish.

    >
    >
    >
    > There are many ways. E.g.
    >
    > class MyString
    > {
    > char *buffer;
    > const char *buffer;
    > bool shallowed;
    >
    >
    > public:
    >
    > MyString(const char *str, bool shallow=false)
    > {
    > shallowed=shallow;
    >
    > if(shallow)
    > const_buffer=str;
    >
    > else
    > {
    > buffer=new new char[strlen(str)+1];
    > // ...
    > }
    > }
    >
    > // ...
    > };
    >
    >
    >
    > However the whole design doesn't look good. You have func1() as a member
    > function, etc.
    >
    >
    > Not to mention why you bother to define your string class, while there
    > is std::string.


    My working environment doesn't like the use of templates. Plus std::string is
    pretty limited. For a good example of a useful string class, look at Java's
    string or Qt's QString. I prefere to use char arrays over std::string.

    ~S
    Shea Martin, Aug 23, 2004
    #16
  17. Shea Martin wrote:

    > I prefere to use char
    > arrays over std::string.



    Do you mean that char arrays provide more features than std::string?






    Regards,

    Ioannis Vranos

    http://www23.brinkster.com/noicys
    Ioannis Vranos, Aug 23, 2004
    #17
  18. Shea Martin

    Daniel T. Guest

    In article <>,
    Shea Martin <> wrote:

    > I have a MyString class:
    > class MyString
    > {
    > public:
    > MyString() {}
    > MyString(const char *str)
    > {
    > _buffer = new char[strlen(str)+1];
    > strcpy(_buffer, str);
    > }
    >
    > void func1(const MyString &str)
    > {
    > printf("str is %s\n", str._buffer);
    > }
    >
    > private:
    > char *_buffer;
    > };
    >
    > Passing func1 a const char *, will result in a deep copy occurring. Because
    > str
    > is const, the deep copy is not necessary. Obviously I can't have my
    > conversion
    > constructor do a shallow copy, unless I know the created object is const.
    >
    > It there a way to differentiate whether a constructor is creating a const
    > object
    > or not?


    Here's an idea:

    ConstString {
    const char* _data;
    public:
    ConstString( const char* d ): _data( d ) { }
    // only include methods that don't change the guts of _data
    std::string modifiable() const { return string( _data ); }
    };

    The above can be used with string literals:

    ConstString s( "Hello" );

    If you want to change the value, you will need to convert it first:

    std::string ss( s.modifiable() );
    ss.append( " world" );
    Daniel T., Aug 24, 2004
    #18
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ZackS
    Replies:
    5
    Views:
    6,791
    Just an Illusion
    Jul 9, 2004
  2. SpamProof
    Replies:
    3
    Views:
    642
    SpamProof
    Dec 1, 2003
  3. dave
    Replies:
    5
    Views:
    589
    William Brogden
    Jul 17, 2004
  4. Tim Smith
    Replies:
    2
    Views:
    852
    Tim Smith
    Dec 15, 2004
  5. Bartholomew Simpson

    class design/ design pattern question

    Bartholomew Simpson, Jun 12, 2007, in forum: C++
    Replies:
    2
    Views:
    447
    Daniel T.
    Jun 12, 2007
Loading...

Share This Page