Thread: How Backwards Functions

  1. #1
    Registered User
    Join Date
    Apr 2003
    Posts
    26

    Question How Backwards Functions

    I have been rambling through different threads on the cprogramming.com borad, and have noticed the function that follows.
    Code:
     Mid(s1, 3, 0) = "123";
    Now I don't know the proper name for this type of function, but from what I read from the thread was that this finction takes the "123" and adds it at position 3 to string s1. Now I would like to make a function similar to the one above, but my c++ book does not cover this type/style of function so I have no idea of how to make this type of function. I would look it up on the internet, but I don't know what to call this type of function. If someone would either give me a referance, or at least told me what to look under I would much apriciate it.

    -JLBShecky
    System
    OS - Microsoft Windows XP Pro
    CPU - AMD Athlon XP 2600+
    Mother Board - Abit KV7
    RAM - 512 Mb DDR (333)

    C++
    Microsoft Visual Studio Pro. 6.0
    MSDN July 2001

  2. #2
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Look up pointers and references, functions: passing by value and passing by reference, classes, constructors, and operator overloading. With about 1 month of studying, you should be able to understand them.

  3. #3
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    Judging by the code, you're talking about the "Duplicate VB Mid" function contest. You can download the contestants code and have a look through it, that might give you some ideas.

    Some words to look up:
    assignment operator
    functor (or function object)
    Also, check out this link: http://www.parashift.com/c++-faq-lite/references.html

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    26
    Yes I was talking about the "Duplicate VB Mid" contest thread. I now about passing by reference and by value, I also know abit about class, constructors, and operator overloading, but as of yet I do not under stand how to get a function to work on the left side of the assinement operator "=". I tried looking for the contestants code for the "Duplicate VB Mid" contest, but I could not find any it. Thanks for the current input.

    -JLBShecky
    System
    OS - Microsoft Windows XP Pro
    CPU - AMD Athlon XP 2600+
    Mother Board - Abit KV7
    RAM - 512 Mb DDR (333)

    C++
    Microsoft Visual Studio Pro. 6.0
    MSDN July 2001

  5. #5
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I don't know anything about the mid function, but my guess is that this line:

    Code:
    Mid(s1, 3, 0) = "123";
    first of all is a constructor, and second it is assigning "123" to s1 (maybe means string 1?)
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Mid(s1, 3, 0) = "123";

    Here's a class designed so you can use that format. It overloads the operator() and the operator=:
    Code:
    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    class A
    {
    public:
    	A(char* f, char* t, int n);
    	A();
    
    	A& operator()(char* str, int b, int c);
    	A& operator=(char* str);
    	
    	void display()
    	{
    		cout<<"flag = "<<flag<<endl;
    		cout<<"text = "<<text<<endl;
    		cout<<"number = "<<number<<endl;
    	}
    
    	~A()
    	{
    		 delete [] flag;
    		 delete [] text;
    	}
    	
    private:
    	char* flag;
    	char* text;
    
    	int number;
    
    };
    
    A::A(char* f, char* t, int n)
    {
    	flag = new char[strlen(f) + 1];
    	strcpy(flag, f);
    	
    	text = new char[strlen(t) + 1];
    	strcpy(text, t);
    
    	number = n;
    }
    
    A::A()
    {
    	flag = new char[4];
    	strcpy(flag, "off");
    
    	text = new char[6];
    	strcpy(text, "empty");
    	
    	number = 1;
    }
    
    A& A::operator()(char* str, int b, int c)
    {
    	number += b;
    	number *= c + 1;
    
    	delete [] flag;
    	flag = new char[strlen(str) + 1];	
    	strcpy(flag, str);
    
    	return *this;
    }
    
    A& A::operator=(char* str)
    {
    
    	delete [] text;
    	text = new char[strlen(str) + 1];
    	strcpy(text, str);
    	return *this;
    }
    
    
    
    
    int main()
    {
    	A Mid("off", "blue", 5);
    	char* s1 = "on";
    
    		
    	Mid(s1, 3, 0) = "123";
    
    
    
    	Mid.display();			
    	return 0;
    }
    Last edited by 7stud; 06-06-2003 at 04:13 AM.

  7. #7
    Registered User
    Join Date
    Aug 2001
    Posts
    223

    Mid function

    I don't see how we would be able to justify a class for this function since it is only really a function in VB and not an object. The simplest approach would be to create a function that takes four arguments instead of three.

    Something like this.

    Mid(s1, 3, 0, "123");
    zMan

  8. #8
    Registered User
    Join Date
    Aug 2001
    Posts
    223

    justify MID as class

    Further more the result must exist in s1 and not in an object.
    zMan

  9. #9
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I don't see how we would be able to justify a class for this function since it is only really a function in VB and not an object.
    I agree that simplicity is best, but C++ gives us the power to do fun things in our spare time as well. :)

    >but as of yet I do not under stand how to get a function to work on the left side of the assinement operator "=".
    You can do it by returning a reference to an object. Unfortunately, strings are much harder to work with this manner, which is probably why there was a contest for it.

    Here's my take on this issue (using the contest's rules and testing procedures), extensive error checking has been omitted:
    Code:
    #include <iostream>
    #include <string>
    
    class StrRef {
        bool dynamic;
        std::string *base;
        int index;
        int overwrite;
    public:
        StrRef(const char *init, int at, int rep);
        StrRef(std::string& init, int at, int rep);
        ~StrRef();
          
        std::string operator=(std::string s);
        std::string operator=(StrRef ref);
          
        operator std::string();
    };
    
    StrRef::StrRef(const char *init, int at, int rep):
        dynamic(true), base(new std::string(init)),
        index(at), overwrite(rep)
    {}
    
    StrRef::StrRef(std::string& init, int at, int rep):
        dynamic(false), base(&init),
        index(at), overwrite(rep)
    {}
    
    StrRef::~StrRef()
    {
        if (dynamic)
            delete base;
    }
    
    std::string StrRef::operator=(std::string s)
    {
        base->replace(index, overwrite, "");
        base->insert(index, s);
        return *base;
    }
    
    std::string StrRef::operator=(StrRef ref)
    {
        base->replace(index, overwrite, "");
        base->insert(index, *ref.base, ref.index, ref.base->length());
        return *base;
    }
    
    StrRef::operator std::string()
    {
        return base->substr(index, overwrite);
    }
    
    StrRef Mid(const char *s, int at, int rep = 0)
    {
        return StrRef(s, at, rep);
    }
    
    StrRef Mid(std::string& s, int at, int rep = 0)
    {
        return StrRef(s, at, rep);
    }
    
    // Contest test program
    int main()
    {
        using namespace std;
    
        bool correct = true;
        string s1,s2;  
        
        //Basic test
        s2 = "0123456789";
        string s3 = Mid(s2,1,4);
        s1 = Mid(s2,1,4);
        s2 = Mid("0123456789",1,4);
        if (s1 != "1234" || s2 != "1234" || s3 != "1234")
            cout << "Basic test incorrect : " << s1, correct=false;
        
        
        //First test
        s1 = "abcdefg";
        Mid(s1, 3, 0) = "123";
        if (s1 != "abc123defg")
            cout << "First test incorrect : " << s1, correct=false;
        
        
        //Second test
        s1 = "abcdefg";
        s2 = "123";
        Mid(s1, 3, s2.size()) = s2;
        if (s1 != "abc123g")
            cout << "Second test incorrect : " << s1, correct=false;
        
        //Third test
        s1 = "abc";
        s2 = "123";
        Mid(s1, 1, 1) = Mid(s2,1);
        if (s1 != "a23c")
            cout << "Third test incorrect : " << s1, correct=false;    
        
        if (correct)
            cout << "All tests correct!";
    
        cin.get();
    }
    Tested on the following compilers:

    G++ 3.2 (no warnings or errors, correct output)
    VC++ 6 (no warnings or errors, correct output)
    DevC++ 4.9.8 (no warnings or errors, correct output)
    Borland C++ 6 (no warnings or errors, correct output)
    Borland C++ 5.5 (no warnings or errors, correct output)
    My best code is written with the delete key.

  10. #10
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Prelude,

    I'm trying to follow your code. For the required functionality:

    std::string mystring = Mid(someotherstring, 2, 5);

    it seems to me that Mid() needs to return a string type or a char* because operator= for the string class has no idea what a StrRef object is, but your Mid() function returns a StrRef object. I think this is the key bit of trickery:

    operator std::string();

    but I don't understand the format of that function. No return type? But, in the function definition you appear to return a string object in your return statement:

    StrRef::operator std::string()
    {
    return base->substr(index, overwrite);
    }

    I think I'm the guy in your avator right now.
    Last edited by 7stud; 06-06-2003 at 08:27 PM.

  11. #11
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361
    operator std::string() allows implicit conversion from class StringRef to std::string, that means that you can use a StringRef in place of an std::string without casting.

    For example, if you had a function with the following signature:
    void DoSomething(std::string& str);
    you'd be able to pass a StringRef object, as the compiler would do the conversion internally by calling operator std::string().

  12. #12
    I lurk
    Join Date
    Aug 2002
    Posts
    1,361

    Re: Mid function

    Originally posted by zMan
    I don't see how we would be able to justify a class for this function since it is only really a function in VB and not an object. The simplest approach would be to create a function that takes four arguments instead of three.

    Something like this.

    Mid(s1, 3, 0, "123");
    So? The rules in VB don't carry over to C++. The objective of the subjective contest was to try and duplicate the functionality and syntax of this VB "function", not to devise the simplest approach to substring replacement.

  13. #13
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Ok, thanks. Now I understand what it does, but I still don't understand the format. Do you know of any links I could go to?

  14. #14
    Registered User
    Join Date
    Apr 2003
    Posts
    2,663
    Is the operator an old style cast? Hmmm...that must be it. What about not having a return type, and then returning a std::string in the return statement? How come you get implicit functionality and aren't required to explicitly make the cast?

    edit: Sheesh! Never mind, it's in my C++ book.
    Last edited by 7stud; 06-06-2003 at 05:40 PM.

  15. #15
    Registered User
    Join Date
    Apr 2003
    Posts
    26
    Due everyone's input I now understand how the works "Mid(s1, 3, 0) = "123";". My main problem was I was just thinking of a plain function and not of using a class. I gust have to start to think more object orientantedly. I also want to say thanks to all the input.

    -JLBShecky
    System
    OS - Microsoft Windows XP Pro
    CPU - AMD Athlon XP 2600+
    Mother Board - Abit KV7
    RAM - 512 Mb DDR (333)

    C++
    Microsoft Visual Studio Pro. 6.0
    MSDN July 2001

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Void Functions Help
    By bethanne41 in forum C++ Programming
    Replies: 1
    Last Post: 05-09-2005, 05:30 PM
  2. Functions and Classes - What did I do wrong?
    By redmage in forum C++ Programming
    Replies: 5
    Last Post: 04-11-2005, 11:50 AM
  3. calling functions within functions
    By edd1986 in forum C Programming
    Replies: 3
    Last Post: 03-29-2005, 03:35 AM
  4. Factory Functions HOWTO
    By GuardianDevil in forum Windows Programming
    Replies: 1
    Last Post: 05-01-2004, 01:41 PM
  5. Shell functions on Win XP
    By geek@02 in forum Windows Programming
    Replies: 6
    Last Post: 04-19-2004, 05:39 AM