Results 1 to 25 of 25

Thread: Adding To A Class

  1. #1

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024

    Adding To A Class

    This might not be possible but I thought I would ask. Is there any way to append public functions to a class with out editing source code?

    What I mean is I am almost finished creating a bunch of custom functions for STL strings and it would be really nice to have be a part of any var that uses STL strings. For example I have a trim function, it would be nice just to do this:

    Code:
    string s;
    s = "blahblah";
    s.trim();
    Or is there another way to do this that I am not thinking of?
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  2. #2
    Lively Member
    Join Date
    Oct 2001
    Posts
    80
    The only thing that comes to my mind is creating a "friend" function. Don't remember the exect syntax of it, but it will basically give that function access to all private variables of that class. The problem for you, I think, is that you don't really know what private variables string has (might be wrong on that, I never use string class)...

  3. #3
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    You can't know. The internals of the basic_string class are implementation-specific.

    You could always derive from basic_string if you wanted.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  4. #4

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    I think that is something along the same lines as what some one else suggested:

    std::string does not have a rich supply of functions. I've always used it as a starting point by creating my own class and using std::string through containment. I use containment because std::string is not meant to be inherited from, as can be seen by the lack of a virtual destructor.

    starting point:

    class MyString
    {
    public:
    // your complete interface here...
    private:
    std::string m_string;
    };

    Any one care to give me some more code to point me in the right direction.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  5. #5
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    You can derive from std::basic_string as long as nothing you do needs to be undone in a constructor. Trim functions and other manipulations are fine to do this with. That also saves you from having to reimplement the things std::basic_string does for you.

    Z.

  6. #6
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Yep. Virtual destructors are only a necessary if you fear that delete might get called on a pointer to a base class that actually points to a derived class that needs to do something important in its destructor.


    There is no way to add methods to an existing class.
    You can't even make some function of yours a friend of an existing class - the friend declaration must be inside the class.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  7. #7

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    This is what some one is suggesting:

    class MyString
    {
    public:
    // various constructors here. Default, one taking const char*,
    // etc.

    // provide for implicit cast to const char*. Some argue against
    // this, but I fiind it convenient.
    operator const char*() const
    {
    return m_string.c_str();
    }

    void trim()
    {
    // your trim implementation here
    }

    // etc. etc. etc.

    private:
    std::string m_string;
    };


    Simply build up your own ideal string class by adding public methods that operate on the m_string member. You could provide an operator[], size(), empty(), subst(), trimLeft(), trimRight(), upper(), lower(), isalpha(), whatever you desire.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  8. #8
    Lively Member
    Join Date
    Oct 2001
    Posts
    80
    Keep in mind that when you define functions within the class declaration those functions are automatically inline, might present some problems with long functions.

  9. #9
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by Technocrat
    This is what some one is suggesting:
    ...
    Simply build up your own ideal string class by adding public methods that operate on the m_string member. You could provide an operator[], size(), empty(), subst(), trimLeft(), trimRight(), upper(), lower(), isalpha(), whatever you desire.
    Yes, but most of those are already implemented by std::basic_string... why add another layer of function calls, or, more to the point, why spend all that time typing them out when you can simply derive from std::basic_string?

    Z.

  10. #10

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Originally posted by Zaei
    Yes, but most of those are already implemented by std::basic_string... why add another layer of function calls, or, more to the point, why spend all that time typing them out when you can simply derive from std::basic_string?

    Z.
    Can you give me a quick code to show me how you might do that?
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Code:
    template<typename C, typename T = std::char_traits<C>, typename A = std::allocator<C> >
    class not_so_basic_string : public std::basic_string<C, T, A>
    {
      // bla bla bla
    };
    You MUST add all those constructors std::basic_string has, else you can't use them.
    Last edited by CornedBee; Jun 6th, 2003 at 04:11 AM.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Code:
    #include <string>
    
    template<typename E, typename T = std::char_traits<E>, typename A = std::allocator<E> >
    class my_basic_string : public std::basic_string<E, T, A>
    {
    public:
      /**/ trim(/**/);
      // your new functions here
    };
    
    typedef my_string my_basic_string<char>;
    Should work, methinks.

    Z.
    Last edited by Zaei; Jun 6th, 2003 at 07:37 AM.

  13. #13

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Hmm sorry Zei but your code didnt compile, but Cornedbee's did.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  14. #14
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Whoops, forgot a word

    Z.

  15. #15

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Yeah I guess class is important I missed it too
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  16. #16

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Man I keep thinking I should have just taken no for an answer. Ok someone had this to say:

    There are two reasons not to inherity from basic_string:

    1. You aren't supposed to. There is no virtual destructor in basic_string, hence it's not meant to be inherited from.

    2. You have less control over the interface. It's possible to get in a position where you don't want the user to call certain methods.

    A better solution would be:

    template<typename C, typename T = char_traits<C>, typename A = allocator<C> >
    class not_so_basic_string
    {
    public:
    // All methods;
    private:
    std::basic_string<C, T, A> m_string;
    }
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  17. #17
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by Technocrat
    Man I keep thinking I should have just taken no for an answer. Ok someone had this to say:

    There are two reasons not to inherity from basic_string:

    1. You aren't supposed to. There is no virtual destructor in basic_string, hence it's not meant to be inherited from.

    2. You have less control over the interface. It's possible to get in a position where you don't want the user to call certain methods.

    A better solution would be:

    template<typename C, typename T = char_traits<C>, typename A = allocator<C> >
    class not_so_basic_string
    {
    public:
    // All methods;
    private:
    std::basic_string<C, T, A> m_string;
    }
    There is no virtual destructor in std::basic_string because a virtual destructor adds a virtual function table to every instance of the class, thus, a size increase, and a performance penalty. As long as you follow the rules of inheritance correctly, there is no reason you cannot inherit from std::basic_string because it doesnt have a virtual destructor.

    Adding your own interface gives you a function call penalty everytime you call a normal std::basic_string member, on top of the normal speed of the call. I am also at a loss for any reason you would want to limit the calling of certain members.

    Z.

  18. #18

    Thread Starter
    Frenzied Member Technocrat's Avatar
    Join Date
    Jan 2000
    Location
    I live in the 1s and 0s of everyones data streams
    Posts
    1,024
    Templates are a bit pass me because I havent gotten around to learn them, but your logic makes sense. It seems to me his solution will cause a great deal of over head and performace issues when alot of these classes are created.

    I am more inclined to believe your answer than his anyways.

    Thanks.
    MSVS 6, .NET & .NET 2003 Pro
    I HATE MSDN with .NET & .NET 2003!!!

    Check out my sites:
    http://www.filthyhands.com
    http://www.techno-coding.com


  19. #19
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    Originally posted by Zaei
    There is no virtual destructor in std::basic_string because a virtual destructor adds a virtual function table to every instance of the class, thus, a size increase, and a performance penalty. As long as you follow the rules of inheritance correctly, there is no reason you cannot inherit from std::basic_string because it doesnt have a virtual destructor.

    Adding your own interface gives you a function call penalty everytime you call a normal std::basic_string member, on top of the normal speed of the call. I am also at a loss for any reason you would want to limit the calling of certain members.

    Z.
    If you use inline functions, then any real function calls should not be affected. Most basic_string calls end up inlined anyway.
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  20. #20
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by parksie
    If you use inline functions, then any real function calls should not be affected. Most basic_string calls end up inlined anyway.
    Only if your compiler inlines

    Z.

  21. #21
    Monday Morning Lunatic parksie's Avatar
    Join Date
    Mar 2000
    Location
    Mashin' on the motorway
    Posts
    8,169
    If it doesn't then either fix it or get a better one
    I refuse to tie my hands behind my back and hear somebody say "Bend Over, Boy, Because You Have It Coming To You".
    -- Linus Torvalds

  22. #22
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by parksie
    If it doesn't then either fix it or get a better one
    Bad argument, eh?

    I know what you mean... but inheriting still saves you a lot of typing to write your own interface =)

    Z.

  23. #23
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Zaei: your code has another problem: it allocates char_traits<C> objects instead of C objects.

    Another thing we both forgot: char_traits and allocator both come from std too. I edited my post.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  24. #24
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by CornedBee
    Zaei: your code has another problem: it allocates char_traits<C> objects instead of C objects.

    Another thing we both forgot: char_traits and allocator both come from std too. I edited my post.
    Would you be surprised to know that I copied and pasted the template declaration from MSDN, the changed "class" to "typename"?

    Z.

  25. #25
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    It's still wrong.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width