overloading [] operator

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • guest
    New Member
    • May 2006
    • 25

    overloading [] operator

    I am trying to overload [] operator like this.

    char* myclass::operat or[](char* str)
    {
    ....
    }

    Basically I should be able to handle these cases

    char* c1=myclass["test"];

    char* c2="test2";
    myclass["test']=c2;

    So, myclass["test"] can appear either in rhs or lhs of an expression. In my operator[] function which has to handle these cases differently, how will I differentiate it?
  • Banfa
    Recognized Expert Expert
    • Feb 2006
    • 9067

    #2
    Originally posted by guest
    So, myclass["test"] can appear either in rhs or lhs of an expression. In my operator[] function which has to handle these cases differently, how will I differentiate it?
    You can't.

    operator[] should return a reference to the data to be written, if you are trying to create an array of strings indexed by strings you have chosen the wrong type the the return of operator[], try

    string &myClass::opera tor[](const char* str)
    {
    }

    Comment

    • guest
      New Member
      • May 2006
      • 25

      #3
      Originally posted by Banfa
      You can't.

      operator[] should return a reference to the data to be written, if you are trying to create an array of strings indexed by strings you have chosen the wrong type the the return of operator[], try

      string &myClass::opera tor[](const char* str)
      {
      }
      Thanks for the correction. And your guess is correct. I am trying to create an array of strings indexed by strings. My problem is that I will create a place holder for the strings only in case of

      myClass[s1]=s2; //creates memory for s1 and s2

      and not in case of

      s3=myClass[s1]; //doesn't create any thing. Just returns reference to indexed string

      So the operator should behave differently in different cases. Is this possible?

      Comment

      • Banfa
        Recognized Expert Expert
        • Feb 2006
        • 9067

        #4
        Originally posted by guest
        myClass[s1]=s2; //creates memory for s1 and s2

        and not in case of

        s3=myClass[s1]; //doesn't create any thing. Just returns reference to indexed string

        So the operator should behave differently in different cases. Is this possible?
        In the second case you will be able to tell because when you look you look the index s1 in whatever method you are using for storage it will already exist. So the operator does this

        Code:
        LOOK UP INDEX
        
        IF IT EXISTS
            RETURN REFERENCE TO EXISTING MEMORY
        ELSE
            CREATE NEW MEMORY
            ASSOCIATE MEMORY WITH INDEX
            RETURN REFERENCE TO NEW MEMORY
        ENDIF
        It does not need to know the context in which is is called.


        You know you could get something extremely similar from

        map<string, string>

        Comment

        • dtimes6
          New Member
          • Oct 2006
          • 73

          #5
          It seems u need something like this:

          Code:
          #include <stdio.h>
          #include <string.h>
          
          class CharPtr {
          private:
          	char* ptr;
          
          public:
          	CharPtr& operator = (char* other) {
          		if(other== ptr)
          			return *this;
          		if(ptr)
          			delete [] ptr;
          		unsigned length = strlen( other);
          		ptr = new char[length];
          		memcpy(ptr,other,length);
          		return *this;
          	}
          	CharPtr(char* other) {
          		unsigned length = strlen( other);
          		ptr = new char[length];
          		memcpy(ptr,other,length);
          	}
          	CharPtr( const CharPtr& other) {
          		unsigned length = strlen( other.ptr);
          		ptr = new char[length];
          		memcpy(ptr,other.ptr,length);
          	}
          	CharPtr& operator=(const CharPtr& other) {
          		if(other.ptr== ptr)
          			return *this;
          		if(ptr)
          			delete [] ptr;
          		unsigned length = strlen( other.ptr);
          		ptr = new char[length];
          		memcpy(ptr,other.ptr,length);
          		return *this;
          	}
          	~CharPtr() { if(ptr) delete [] ptr; }
          	CharPtr() :ptr(NULL){}
          	operator char* () {
          		return ptr;
          	}
          };
          
          class T {
          private:
          	CharPtr a;
          public:
          	CharPtr& operator[]( const CharPtr& key) {
          		return a;
          	}
          };
          
          int main()
          {
          	T a;
          	a["text"] = "putin";
          	printf("%s", (char*)a["text"]);
          	return 0;
          }

          Comment

          • guest
            New Member
            • May 2006
            • 25

            #6
            Thanks for the code, but it does not address multiple key value issue. For ex, if you changed main() like this,

            Code:
            int main()
            {
            	T a;
            	a["text"] = "putin";
            	a["text2"] = "putin2";
            	printf("%s", (char*)a["text"]);
            	return 0;
            }
            Still it will output putin2. In other words, it always has placeholder for the latest string assigned. Key is just discarded and has no significance at all.

            In the algorithm

            Code:
            LOOK UP INDEX
            
            IF IT EXISTS
                RETURN REFERENCE TO EXISTING MEMORY
            ELSE
                CREATE NEW MEMORY
                ASSOCIATE MEMORY WITH INDEX
                RETURN REFERENCE TO NEW MEMORY
            ENDIF
            there is a flaw. If the index does not exist, it creates memory associated to that index. But if it is an rvalue (like in s2=myclass[s1]; ) and it does not exist, it has to just return null. Memory should not be created (and wasted).

            Comment

            • Banfa
              Recognized Expert Expert
              • Feb 2006
              • 9067

              #7
              Originally posted by guest
              there is a flaw. If the index does not exist, it creates memory associated to that index. But if it is an rvalue (like in s2=myclass[s1]; ) and it does not exist, it has to just return null. Memory should not be created (and wasted).
              You should not be trying to access an array index that does not exist as an rvalue. You can not return a reference to nothing.

              Comment

              • Banfa
                Recognized Expert Expert
                • Feb 2006
                • 9067

                #8
                Originally posted by dtimes6
                Code:
                class CharPtr {
                public:
                	CharPtr& operator = (char* other) {
                		if(other== ptr)
                			return *this;
                		if(ptr)
                			delete [] ptr;
                		unsigned length = strlen( other);
                		ptr = new char[length];
                		memcpy(ptr,other,length);
                		return *this;
                	}
                <snipped>
                };
                
                class T {
                private:
                	CharPtr a;
                public:
                	CharPtr& operator[]( const CharPtr& key) {
                		return a;
                	}
                };
                
                int main()
                {
                	T a;
                	a["text"] = "putin";
                	printf("%s", (char*)a["text"]);
                }
                Although the method is workable as written it will go wrong because in the overload of operator[] you only allocate space for the characters of "putin" you do not allocate space or write a terminating '\0' character so when you cast to (char *) and just use it as a normal C zero terminated string it will go wrong because there is no terminating zero.

                Comment

                • dtimes6
                  New Member
                  • Oct 2006
                  • 73

                  #9
                  Originally posted by Banfa
                  You should not be trying to access an array index that does not exist as an rvalue. You can not return a reference to nothing.
                  That is not nothing that is a NULL pointer.

                  Comment

                  • dtimes6
                    New Member
                    • Oct 2006
                    • 73

                    #10
                    Originally posted by Banfa
                    Although the method is workable as written it will go wrong because in the overload of operator[] you only allocate space for the characters of "putin" you do not allocate space or write a terminating '\0' character so when you cast to (char *) and just use it as a normal C zero terminated string it will go wrong because there is no terminating zero.
                    Yes u right. It needs to copy one more char '\0'

                    Comment

                    • Banfa
                      Recognized Expert Expert
                      • Feb 2006
                      • 9067

                      #11
                      Originally posted by dtimes6
                      That is not nothing that is a NULL pointer.
                      The whole point is it shouldn't be a pointer it should be a reference and you can not return a reference to nothing.

                      Comment

                      • dtimes6
                        New Member
                        • Oct 2006
                        • 73

                        #12
                        Originally posted by Banfa
                        The whole point is it shouldn't be a pointer it should be a reference and you can not return a reference to nothing.
                        But he can return a CharPtr(), that is fine.

                        Comment

                        Working...