Extending string class

Discussion in 'C++' started by Carl Youngblood, Jul 8, 2004.

  1. I imagine this subject has probably been brought up numerous times.
    Forgive me for bringing it up again. I was googling through old posts
    on this newsgroup about it and found a good suggestion on how to add
    functionality to the string class. Rather than trying to inherit from
    the string class, the author was suggesting wrapping the string class
    in another class, like so:

    >Right !!!, we should not derive from string, but we should wrap the
    >string class, for example.
    >
    >class Mystring {
    > string data;
    >
    > Mystring(char* x) : data(x){};
    > Mystring(string* x) : data(x){};
    >
    > Mystring& operator=(const Mystring& x){
    > data=x.data;
    > return *this.
    > }
    >}


    The only confusing thing about his post was that he said this at the
    end:

    >This is actually a very easy thing to do. You just have to check all

    the
    >interface functions of string class (which is basic_string<char>) and

    do the
    >same inline like above. The new class will have about the same

    efficiency as
    >the std::string class one (because of the inlining), however, you

    will be
    >able to extend your own additions of behaviors. Don't forget to

    define the
    >value type, iterator type and reference type, like this ....
    > typename string::value_type value_type;
    >and etc .....


    I don't know exactly what he meant by "Don't forget to define the
    value type, iterator type and reference type". I've done a good bit
    of C++ programming but am by no means an expert.

    Thanks for your help,

    Carl Youngblood
    Carl Youngblood, Jul 8, 2004
    #1
    1. Advertising

  2. Carl Youngblood wrote:
    > I imagine this subject has probably been brought up numerous times.
    > Forgive me for bringing it up again. I was googling [...]


    I think you should consider reading a decent book on the Standard C++
    containers and iterators (and other parts of the library).

    > [...]
    >
    > I don't know exactly what he meant by "Don't forget to define the
    > value type, iterator type and reference type". I've done a good bit
    > of C++ programming but am by no means an expert.


    std::basic_string is a standard class template that is made compatible
    with standard algorithms by implementing (declaring) types that the
    algorithms expect from any other compliant container. If you find
    a good book on C++ library, its algorithms, and how to implement your
    own container (or a container template), you'd see how those "value
    type, iterator type and reference type" are used. In essence, you
    need to do something like

    class MyString {
    string data;

    typedef string::value_type value_type;
    typedef string::reference reference;
    typedef string::iterator iterator;

    and so on. You will basically re-declare those types to be valid
    types in the scope of your class, so that anybody who needs them can
    use MyString::value_type instead of figuring out what that type should
    be...

    Victor
    Victor Bazarov, Jul 8, 2004
    #2
    1. Advertising

  3. Carl Youngblood

    Phlip Guest

    Carl Youngblood wrote:

    > I imagine this subject has probably been brought up numerous times.
    > Forgive me for bringing it up again. I was googling through old posts
    > on this newsgroup about it and found a good suggestion on how to add
    > functionality to the string class. Rather than trying to inherit from
    > the string class, the author was suggesting wrapping the string class
    > in another class, like so:
    >
    > >Right !!!, we should not derive from string, but we should wrap the
    > >string class, for example.
    > >
    > >class Mystring {
    > > string data;
    > >
    > > Mystring(char* x) : data(x){};
    > > Mystring(string* x) : data(x){};
    > >
    > > Mystring& operator=(const Mystring& x){
    > > data=x.data;
    > > return *this.
    > > }
    > >}

    >
    > The only confusing thing about his post was that he said this at the
    > end:
    >
    > >This is actually a very easy thing to do. You just have to check all

    > the
    > >interface functions of string class (which is basic_string<char>) and

    > do the
    > >same inline like above. The new class will have about the same

    > efficiency as
    > >the std::string class one (because of the inlining), however, you

    > will be
    > >able to extend your own additions of behaviors. Don't forget to

    > define the
    > >value type, iterator type and reference type, like this ....
    > > typename string::value_type value_type;
    > >and etc .....

    >
    > I don't know exactly what he meant by "Don't forget to define the
    > value type, iterator type and reference type". I've done a good bit
    > of C++ programming but am by no means an expert.


    It's bad advice.

    There are two kinds of classes: Library classes, and application-specific
    classes.

    Library classes must have extraordinarily wide interfaces, to ensure they
    see use. Iterators and traits permit std::string to satisfy many many more
    situations than any single application should ever use.

    Application-specific classes must have the narrowest interfaces possible to
    do their jobs. If an application-specific class delegates to a library
    class, it should HIDE that super-wide interface, not reveal every stinkin'
    permutation of it.

    Do not ever add any method anywhere that nobody needs, right now. Prove
    every method works with both unit tests and with re-use among other
    application classes that are themselves unit-tested.

    The more methods a class exposes, the less flexible that class's internals
    become. If you needed to replace std::string with CString or _bstr_t (and
    you might find legitimate reasons to do so), your change should be as simple
    as replacing MyString's data, and then trivially re-writing each method.
    When all of MyString's tests pass, integrate and run all integration tests,
    and you are done.

    That refactor would be incredibly difficult if you wrote every method
    std::string uses, and if application code then called all of those methods.

    --
    Phlip
    http://industrialxp.org/community/bin/view/Main/TestFirstUserInterfaces
    Phlip, Jul 8, 2004
    #3
  4. Carl Youngblood

    David Hilsee Guest

    "Carl Youngblood" <> wrote in message
    news:...
    > I imagine this subject has probably been brought up numerous times.
    > Forgive me for bringing it up again. I was googling through old posts
    > on this newsgroup about it and found a good suggestion on how to add
    > functionality to the string class. Rather than trying to inherit from
    > the string class, the author was suggesting wrapping the string class
    > in another class, like so:
    >
    > >Right !!!, we should not derive from string, but we should wrap the
    > >string class, for example.
    > >
    > >class Mystring {
    > > string data;
    > >
    > > Mystring(char* x) : data(x){};
    > > Mystring(string* x) : data(x){};
    > >
    > > Mystring& operator=(const Mystring& x){
    > > data=x.data;
    > > return *this.
    > > }
    > >}

    >
    > The only confusing thing about his post was that he said this at the
    > end:
    >
    > >This is actually a very easy thing to do. You just have to check all

    > the
    > >interface functions of string class (which is basic_string<char>) and

    > do the
    > >same inline like above. The new class will have about the same

    > efficiency as
    > >the std::string class one (because of the inlining), however, you

    > will be
    > >able to extend your own additions of behaviors. Don't forget to

    > define the
    > >value type, iterator type and reference type, like this ....
    > > typename string::value_type value_type;
    > >and etc .....


    These "extensions" are probably best provided as non-member functions,
    possibly in some string utility namespace for your application. Most
    likely, creating a separate string class will not add any value, and it will
    only create overhead when the client has to copy the string's contents into
    an instance of your class to to invoke the member functions in that class.
    I say "probably" because the description you gave leads me to believe that
    you have no intention of hiding the std::string implementation from the
    users of the class. If that is true, then do not bother creating a separate
    class to hold your utility functions for std::string, as it will not provide
    anything that non-member ("free") functions could also provide with less
    overhead. If your intention is to keep the class's clients from depending
    on std::string, then this class may have some merit, as Phlip described.

    --
    David Hilsee
    David Hilsee, Jul 9, 2004
    #4
  5. Thanks for all your advice. I'm sorry but the easiest way to handle
    to problem was to write a helper function in another namespace, as the
    last post suggested. However, this just doesn't sit well with me from
    an OO standpoint. If I'm adding functionality that someone would want
    on a string, it seems like I should be able to add it to the string
    class, or a class derived from it, but this is a monumental task in
    C++, akin to swimming the English channel or something. It appears
    that I've spent too much time in VHLLs like Ruby. Thanks anyway for
    your help.
    Carl Youngblood, Jul 10, 2004
    #5
    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. Simon Elliott
    Replies:
    0
    Views:
    360
    Simon Elliott
    Jan 11, 2005
  2. Matthias Kaeppler
    Replies:
    1
    Views:
    321
    Kanenas
    Apr 22, 2005
  3. Rakesh
    Replies:
    10
    Views:
    12,132
    Mike Schilling
    Apr 8, 2008
  4. peter koch
    Replies:
    6
    Views:
    370
    James Kanze
    Mar 24, 2009
  5. James Kanze
    Replies:
    1
    Views:
    340
    James Kanze
    Mar 20, 2009
Loading...

Share This Page